简体   繁体   中英

How to correctly specify the copy constructor

Assume I have a class Matrix, with a constructor as follows:

Matrix::Matrix(int rows, int cols)
{
    nrows = a; //here nrows is the number of rows for each matrix 
    ncols = b; //here ncols is the number of cols for each matrix
    p = new double [rows*cols];
    for(int i=0;i<rows*cols;i++) 
        { 
            *p++ = 0.0;
        }
}

Suppose I also have a 'copy' constructor as follows:

Matrix::Matrix(const Matrix& mat)
{   p = new double[mat.nrows*mat.ncols];
    for(int i=0;i<mat.nrows*mat.ncols;i++)
        { 
             p[i] = mat.p[i];

        }
}

Now also suppose I have the following lines in my main function:

int main()
    {
        Matrix A(2,2);
        Matrix B(2,2);
        A = Matrix(B); //call overloaded assignment operator, and copy ctor/
     }

Here the '=' operator is overloaded to assign all the elements in B to A. My issue is that once the call to the copy constructor is made, the Matrix A object is a completely new object.

Is there a better way of writing the copy constructor so that if Matrix A already exists then calling A = Matrix(B) results in an error?

Instead of using dynamically allocated arrays, I would recommend using std::vector

class Matrix
{
public:
    Matrix(long rows, long cols);
private:
    long nrows;
    long ncols;
    std::vector<double> p;
}

Then your constructor can be

Matrix::Matrix(long rows, long cols)
: nrows(rows),
  ncols(cols),
  p(rows * cols)
{ }

Along with all of the other benefits of using std::vector over dynamically allocated arrays, you now get a compiler-generated copy constructor, so you don't need to write one.

If you don't want your class to be copyable, delete the copy constructor and copy assignment operator.

class Matrix
{
public:
    Matrix(long rows, long cols);
    Matrix(const Matrix& mat) = delete;
    Matrix& operator=(const Matrix& mat) = delete;
private:
    long nrows;
    long ncols;
    std::vector<double> p;
}

With the statement

A = Matrix(B);

first a temporary object is create using the copy-constructor. This temporary object is then used in the assignment.

So it's true that the copy-constructor is used, but not as part of the assignment.

It would be far better to delete the assignment operator:

Matrix& operator=(const Matrix&) = delete;

Then use of A = Matrix(B) would emit a compile time error. You'd then be forced to use the constructor and your specific issue would cease to be relevant.

No. Because then it wouldn't be a copy constructor . A constructor constructs.

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