C++ 复制构造函数…怎么了?

C++ 复制构造函数…怎么了?,c++,C++,所以我的问题是…当我试图为指针分配内存时,它失败了 这是我的MatrixClass定义 class MatrixClass { public: MatrixClass(int m, int n); MatrixClass(void); virtual ~MatrixClass(void); double getRead(int num1, int num2) const; double& getReadWrite(int num3, int num

所以我的问题是…当我试图为指针分配内存时,它失败了

这是我的MatrixClass定义

class MatrixClass
{
public:
    MatrixClass(int m, int n);
    MatrixClass(void);
    virtual ~MatrixClass(void);
    double getRead(int num1, int num2) const;
    double& getReadWrite(int num3, int num4);
    void set(int i,int j,double value);//set value at i,j to value
    MatrixClass(const MatrixClass &rhs);
    void assign(int M,int N);
    MatrixClass sum1(const MatrixClass& rhs) const;
    MatrixClass operator+(const MatrixClass& rhs);//overloading the + operator 
    MatrixClass operator-();
private:
    double* dataptr;
    int M;
    int N;
};
我正在努力做到这一点

MatrixClass BB;
BB = A + B;
这是我的重载+函数

MatrixClass MatrixClass::operator +(const MatrixClass &rhs)
{
    MatrixClass temp;
    //temp.M = this->M + rhs.M;
    //temp.N = this->N + rhs.N;
    for(int i = 0;i < M;i++)
    {
        for(int j = 0; j<N;j++)
        {
            temp.dataptr[i * N + j] = this->getReadWrite(i,j) + rhs.dataptr[i*N+j];
        }
    }   
    return temp;
}//end operator +
我得到的错误也是…'在Advuto.EXE中的0x75 A0B727未处理异常:微软C++异常:STD::BADYOLL在内存位置0x02AF924..…/P> 所以基本上我要问的问题是..为什么我试图在复制构造函数中为'dataptr'分配内存的那一行给了我问题..它只在从返回值'temp'调用复制构造函数时才这样做


谢谢

简短回答:您没有正确实施

详细回答:您尚未实现
操作符=
。编译器生成的一个对于您的案例来说是不够的

除此之外,我猜想默认构造函数不会为
dataptr
分配内存。如果是这样,那么您正在
operator+
中使用
dataptr
,甚至没有为它分配内存。这就是程序崩溃的原因。即使默认构造函数分配内存,问题仍然存在,因为
rhs.M
rhs.N
的值可能不同于您在默认构造函数中假设的值(正如您所说,
4
5


因此,在
operator+
中为
dataptr
分配内存。另外,在分配之前,您必须解除分配它可能指向的内存,并且您还需要将
M
N
分别设置为
rhs.M
rhs.N

简短回答:您没有正确实现

详细回答:您尚未实现
操作符=
。编译器生成的一个对于您的案例来说是不够的

除此之外,我猜想默认构造函数不会为
dataptr
分配内存。如果是这样,那么您正在
operator+
中使用
dataptr
,甚至没有为它分配内存。这就是程序崩溃的原因。即使默认构造函数分配内存,问题仍然存在,因为
rhs.M
rhs.N
的值可能不同于您在默认构造函数中假设的值(正如您所说,
4
5


因此,在
operator+
中为
dataptr
分配内存。另外,在分配之前,您必须释放它可能指向的内存,并且您还需要将
M
N
分别设置为
rhs.M
rhs.N

不,詹姆斯,您错了,当
operator+
返回时,将调用复制构造函数将局部变量
temp
转换为赋值运算符范围内的临时匿名对象。在复制构造函数中,
将引用此临时变量,而不是BB

因为LHS已经存在,当
operator+
返回时将不会再次“构造”它,它将被“分配”,因此您需要重载
operator=
。(更多详细信息,请参阅。)默认的
操作符=
只进行按位复制,因此,如果没有重载操作符=,则当匿名临时对象超出范围(复制后立即)被销毁时,
dataptr
将在匿名临时对象的析构函数中释放(我们希望如此)BB将指向释放的内存。您还将泄漏BB中已分配的任何内存,因为BB在分配之前不会被销毁。BB的
dataptr
将泄漏,而临时对象的
dataptr
将释放两次

因此,虽然分配和复制内存三次有点糟糕,但为了使+和=在所有情况下都能工作,您需要执行以下操作:

  • 操作员+
    更改
    矩阵类温度
    矩阵类温度(rhs.M,rhs.N)以便正确分配和解除分配
    临时数据PTR
  • 在复制构造函数中,为
    dataptr
    分配新内存并将其复制
  • 重载
    运算符=
    ,以便它首先检查自分配
    (this==&rhs)
    ,如果不是自分配,则释放现有的
    数据ptr
    ,然后分配一个新数据并复制
    rhs

不,詹姆斯,你错了,当
操作符+
返回复制构造函数时,将调用该构造函数将局部变量
temp
转换为赋值操作符范围内的临时匿名对象。在复制构造函数中,
将引用此临时变量,而不是BB

因为LHS已经存在,当
operator+
返回时将不会再次“构造”它,它将被“分配”,因此您需要重载
operator=
。(更多详细信息,请参阅。)默认的
操作符=
只进行按位复制,因此,如果没有重载操作符=,则当匿名临时对象超出范围(复制后立即)被销毁时,
dataptr
将在匿名临时对象的析构函数中释放(我们希望如此)BB将指向释放的内存。您还将泄漏BB中已分配的任何内存,因为BB在分配之前不会被销毁。BB的
dataptr
将泄漏,而临时对象的
dataptr
将释放两次

因此,虽然分配和复制内存三次有点糟糕,但为了使+和=在所有情况下都能工作,您需要执行以下操作:

  • 操作员+
    更改
    矩阵类温度
    矩阵类温度(rhs.M,rhs.N)以便正确分配和解除分配
    临时数据PTR
  • 正如你所做的
    MatrixClass::MatrixClass(const MatrixClass &rhs)//copy constructor
    {
        this->M = rhs.M;
        this->N = rhs.N;
        dataptr = 0;
        if(rhs.dataptr != 0)
        {
            dataptr = new double[M * N];//allocate memory for the new object being assigned to...
            // the line here where I try to allocate memory gives me an error.....Am I right in
            //thinking that this would be assigning memory to dataptr of 'BB'?? Values are assigned to //'M' and 'N' fine....
            int num = sizeof(double);
            memcpy(this->dataptr,rhs.dataptr,M*N*sizeof(double));   
        }
        else
        {
            this->dataptr = 0;
        }
    }//end copy constructor