从函数返回,具有动态字段的对象 c++

Posted

技术标签:

【中文标题】从函数返回,具有动态字段的对象 c++【英文标题】:return from function, object with dynamic fields c++ 【发布时间】:2015-10-03 12:47:05 【问题描述】:

我有一个名为Matrix 的类,它包含一个动态存储的字段。还有一个名为Multiply() 的方法必须返回乘以 2 矩阵的结果。问题是我定义了一个析构函数,当我返回时,存储结果矩阵的变量会得到一些随机值,我猜这是因为新变量与临时矩阵具有相同的地址。如何正确退货?

class Matrix
    double **val;
    int rows,cols,errorCode;
public:
    Matrix();
    Matrix(int);
    Matrix(int, int);
    ~Matrix();
    void Print();
    void Read();
    void Realoc(int, int );
    void Assign(int,int,double);
    Matrix Multiply(Matrix&);
    void Multiply(double);
;

Matrix Matrix::Multiply(Matrix &a)
    if(cols != a.rows)
        Matrix b;
        b.errorCode=112; //That means matrices are not compatible;
        cout<<"WARNING! Error "<<errorCode<<" has occurred. "<<endl;
        return b;
    
    else
            //Making a new matrix where we save computed values;
        Matrix b;
        b.Realoc(rows,a.cols);


            //Computing values;
        double  p;
        for(int i=0;i<rows;i++)
            for(int j=0;j<a.cols;j++)
                p=0;
                for(int k=0;k<cols;k++)p += val[i][k]*a.val[k][j];
                b.Assign(i+1,j+1,p);
            
        
        return b;
    


int main()



Matrix a,b(2,2);
b.Assign(1,1,0);
b.Assign(1,2,3);
b.Assign(2,1,5);
b.Assign(2,2,5);
b.Print();

a.Read();
cout<<endl;
cout<<"'a' multiplied by 'b' is: "<<endl;
Matrix m;
m = a.Multiply(b);
m.Print();
cout<<endl;
return 0;

一些想法?

附:我做了复制构造函数,但它没有任何好的结果。

这是我制作的复制构造函数。

Matrix::Matrix(Matrix &a)
    rows = a.rows;
    cols = a.cols;
    errorCode = 0;
    val = new double*[rows];
    for(int i = 0;i<rows;i++)
        val[i] = new double[cols];
    
    for(int i=0;i<rows;i++)
        for(int j=0;j<cols;j++)
            val[i][j] = a.val[i][j];
        
    

和析构函数:

Matrix::~Matrix()
    for(int i=0;i<rows;i++)
        delete[] val[i];
    
    delete[] val;

【问题讨论】:

不要使用double **val;,而是使用std::vector&lt;std::vector&lt;double&gt;&gt;。这样,默认的复制 ctor 和赋值运算符将为您工作。 我们需要查看您的析构函数,但我认为您的问题可以通过实现复制构造函数来解决(并且移动构造函数在您的情况下也很有用)。顺便说一句,除非这是为了学习 C++,否则我强烈建议使用现有的线性代数库而不是使用您自己的容器。 这是使用**的条件。是的,它是为了学习:) 【参考方案1】:

这个:

m = a.Multiply(b);

正在调用赋值运算符而不是复制构造函数,因为 m 已经被默认构造。当您处理动态内存分配时,默认赋值运算符将不够好。您将需要实现自己的赋值运算符。我建议你看看What is The Rule of Three?

我还建议您只使用像 std::vector&lt;std::vector&lt;double&gt;&gt; 这样的 2d std::vector,因为编译器提供的默认值会为您工作。正如您所说,使用double** 是一项要求,您需要自己实现构造函数和赋值运算符。

【讨论】:

以上是关于从函数返回,具有动态字段的对象 c++的主要内容,如果未能解决你的问题,请参考以下文章

具有动态模型的 Dapper ORM - 如何不返回字段而不是“字段”= NULL?

从 C 中的函数返回一个 `struct`

从函数 C++ 返回向量

如何从Combiner/Reducer/Aggregator 函数返回具有多个字段的元组?

将带有结构字段的结构从 c++ 返回到 c# pinvoke

从返回域对象列表的 RESTful Web 服务端点的响应中动态过滤字段