You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++报错const Dataset作为this参数丢弃限定符如何解决?

问题解决方法

错误原因

编译错误的核心原因是:const修饰的Dataset对象只能调用const成员函数,但你当前的Dataset类和内部嵌套的Row类都只提供了非const版本的operator[],调用B[k][j]时,const对象B调用非const的operator[]会丢弃const限定符,不符合C++语法规则。

修复步骤

你需要补充两个const版本的operator[]实现,同时优化相关接口的const兼容性:

  • 给内部Row类新增const版本的下标运算符,用于只读访问行内元素
  • 给外层Dataset类新增const版本的下标运算符,用于只读访问数据集的行
  • 同步修改拷贝构造函数的入参为const引用,保证const对象可以正常拷贝
  • 可选优化赋值运算符逻辑,增加尺寸不匹配时的内存重分配,避免越界访问

修改后完整代码(关键改动已标注)

#include <iostream>
using namespace std;
typedef unsigned int uInt32;

template <class StorageType> class Dataset  
{
private:
    class Row
    {
        private:
            uInt32 NCol;
            StorageType *Data;
        public:
            Row(){
                Data = NULL;
            }
            void SetCol(uInt32 Col){
                if((Data = new StorageType[Col]) == NULL)
                {
                    cout << "Dataset::memory exhausted ... exiting" << endl;
                    exit(1);
                }
                NCol = Col;
            }
            ~Row(){
                if(Data != NULL)
                {
                    delete []Data;
                }
            }
            // 原有非const版本,用于修改元素
            StorageType &operator[](uInt32 Col){
                return Data[Col];
            }
            // 新增const版本,用于只读访问const Row的元素
            const StorageType &operator[](uInt32 Col) const {
                return Data[Col];
            }
    };
    Row *Array;
    uInt32 NRow;
    uInt32 NCol;
public:
    Dataset(uInt32 Row, uInt32 Col)
    {
        if((Array = new Row[Row]) == NULL){
            cerr << "Dataset::memory exhausted ... exiting" << endl;
            exit(1);
        }
        register uInt32 i;
        for(i = 0;i < Row;i++)
        {
            Array[i].SetCol(Col);
        }
        NRow = Row;
        NCol = Col;
    }

    // 拷贝构造函数入参改为const引用,兼容const对象拷贝
    Dataset(const Dataset<StorageType> &B)
    {
        NRow = B.GetNoOfRows();
        NCol = B.GetNoOfCols();

        if((Array = new Row[NRow]) == NULL){
            cerr << "Dataset::memory exhausted ... exiting" << endl;
            exit(1);
        }

        register uInt32 i,j;

        for(i = 0;i < NRow;i++)
        {
            Array[i].SetCol(NCol);
            for(j = 0;j < NCol;j++)
            {
                Array[i][j] = B[i][j];
            }
        }
    }

    virtual ~Dataset()
    {
        delete[] Array;
    }

    // 原有非const版本,用于修改行元素
    Row &operator[](uInt32 Row){
        return Array[Row]; 
    }
    // 新增const版本,用于只读访问const Dataset的行
    const Row &operator[](uInt32 Row) const {
        return Array[Row];
    }

    uInt32 GetNoOfRows() const
    {
        return NRow;
    }

    uInt32 GetNoOfCols() const
    {
        return NCol;
    }

    Dataset<StorageType> operator*(Dataset<StorageType> const &B)
    {
        Dataset<StorageType> Temp(NRow,B.GetNoOfCols());

        if(NCol == B.GetNoOfRows())
        {

            uInt32 Row = B.GetNoOfRows();
            uInt32 Col = B.GetNoOfCols();
            register uInt32 i, j, k;
            register StorageType Product;
        
            for(i = 0;i < NRow;i++)
            {
                for(j = 0;j < Col;j++)
                {
                    Product = 0;
                    for(k = 0;k < Row;k++)
                    {
                        Product += Array[i][k]*B[k][j]; // 此处错误已修复
                    }
                    
                    Temp[i][j] = Product;
                }
            }
        }
        else
        {
            cerr << "Dataset::matrices aren't compatible for multiplication" << endl;
        }
        return (Temp);
    }

    // 赋值运算符优化:增加尺寸不匹配时的内存重分配逻辑,避免越界访问
    void operator=(Dataset<StorageType> const &B)
    {
        // 如果当前尺寸和待赋值对象尺寸不一致,先释放原有内存重新分配
        if(NRow != B.GetNoOfRows() || NCol != B.GetNoOfCols()){
            delete[] Array;
            NRow = B.GetNoOfRows();
            NCol = B.GetNoOfCols();
            Array = new Row[NRow];
            for(uInt32 i=0;i<NRow;i++){
                Array[i].SetCol(NCol);
            }
        }

        register uInt32 i, j;

        uInt32 Row = B.GetNoOfRows();
        uInt32 Col = B.GetNoOfCols();

        for(i = 0;i < Row;i++)
        {
            for(j = 0;j < Col;j++)
            {
                Array[i][j] = B[i][j]; // 此处错误已修复
            }
        }
    }
};

功能验证用例

int main(){
    Dataset<double> a(2,3);
    Dataset<double> b(3,2);
    // 初始化a和b的元素
    for(int i=0;i<2;i++){
        for(int j=0;j<3;j++){
            a[i][j] = i*3 + j + 1;
        }
    }
    for(int i=0;i<3;i++){
        for(int j=0;j<2;j++){
            b[i][j] = i*2 + j + 1;
        }
    }
    // 测试const参数的乘法
    Dataset<double> c = a * b;
    // 输出结果
    for(int i=0;i<c.GetNoOfRows();i++){
        for(int j=0;j<c.GetNoOfCols();j++){
            cout << c[i][j] << " ";
        }
        cout << endl;
    }
    return 0;
}

内容的提问来源于stack exchange,提问作者Nostalgic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 20:00:04