C++ 复制构造函数…怎么了?
所以我的问题是…当我试图为指针分配内存时,它失败了 这是我的MatrixClass定义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
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