当我执行a = b之类的操作时它工作正常但是如果我执行a = a,则向量中的所有元素得到-1.255 + -67。这是我的复制构造函数和赋值运算符:
VecXd(const VecXd &source){
dimension = source.dimension;
vector = new T[dimension];
for(int i=0; i < dimension; i++)
vector[i] = source.vector[i];
}
VecXd operator=(const VecXd &source){
dimension = source.dimension;
vector = new T[dimension];
for(int i=0; i < dimension; i++)
vector[i] = source.vector[i];
return *this;
}
答案 0 :(得分:4)
这是因为一旦分配了新的向量,就会丢失source.vector的先前值。这是一个自我赋值,因此source引用与* this相同的对象,因此vector和source.vector是同一个。
您可以解决此问题以及内存泄漏,如下所示:
VecXd operator=(const VecXd &source){
dimension = source.dimension;
T *temp = new T[dimension]; // Don't loose source.vector yet
for(int i=0; i < dimension; i++)
temp[i] = source.vector[i];
delete [] vector; // Delete old vector
vector = temp;
return *this;
}
更好的是,你可以防止自我指派,以防止这种讽刺:
VecXd operator=(const VecXd &source){
if(this == &source)
return *this; // This is a self-assignment, so there's nothing to do
delete [] vector; // Delete old vector
dimension = source.dimension;
vector = new T[dimension]; // Now we are sure that vector and source.vector differ
for(int i=0; i < dimension; i++)
vector[i] = source.vector[i];
return *this;
}
答案 1 :(得分:3)
如果两个向量相同,则该行消除源向量的内容:
vector = new T[dimension];
因此,复制循环发生的下一行,您正在将垃圾读入垃圾箱。对于真正安全的赋值运算符/复制构造函数,请使用copy-swap pattern
答案 2 :(得分:1)
定义自定义赋值运算符时,始终必须处理“自我赋值”情况。 小样本:
Shape& Shape::operator=(const Shape& S) //Assignment operator overloading
{
if(this==&source) //Checking for self assignment.
{
return *this;
}
m_id=S.m_id;
return *this;
}
答案 3 :(得分:1)
简短回答:你覆盖了你的vector
指针,丢失了数据(以及泄漏内存)。
实现赋值运算符的最简单方法是复制和交换习惯用法:
void swap(VecXd & other) {
using std::swap;
swap(dimension,other.dimension);
swap(vector,other.vector);
}
VecXd& operator=(const VecXd &source){
VecXd cpy (source);
swap(cpy);
return *this;
}
这是一个很好的选择,因为:
delete
Bonus 如果交换运算符没有抛出(应该如此),这可以保证强大的异常安全性,即如果赋值运算符抛出(通过复制构造函数),则对象的状态保持不变
答案 4 :(得分:0)
VecXd operator=(const VecXd &source){
dimension = source.dimension;
vector = new T[dimension];
for(int i=0; i < dimension; i++)
vector[i] = source.vector[i];
^
here you assign uninitialized vector values
to the same vector
return *this;
}
引用尚未构造或已被破坏的对象的非静态成员是未定义的行为。此外返回参考不值:
VecXd& operator=(const VecXd &source){
// ...
return *this;
}
这可以启用链分配a=b=c
并检查自我分配:
VecXd& operator=(const VecXd &source){
if(this!=&source) {
// ... do what needed
}
return *this;
}