简体   繁体   中英

return from function, object with dynamic fields c++

I have a class named Matrix that contains one field that is stored dynamic. And a method named Multiply() that has to return the result of multiplying 2 Matrix. Problem is that I defined a destructor and when I return, variable which stores the resultant Matrix get some random values, I guess it happens because new variable have the same address as temporary Matrix. How can I return it correctly?

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;
}

Some ideas?

PS I made copy constructor but it do not do any good result.

Here is a copy constructor I made.

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];
        }
    }
}

And destructor:

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

This:

m = a.Multiply(b);

Is calling the assignment operator and not the copy constructor as m has already been default constructed. The default assignment operator is not going to be good enough as you are dealing with dynamic memory allocation. You will need to implement you own assignment operator. I suggest you take a look at What is The Rule of Three?

I would also suggest you just use a 2d std::vector like std::vector<std::vector<double>> as with it the defaults provided by the compiler would work for you. As you said it is a requirement to use a double** you will need to implement the constructors and assignment operator yourself.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM