1.overloading assignment operator
1.首先需要区分一下copy constructor(拷贝构造)和 copy assignment(拷贝赋值)
sidenote:这里是引用的一个生活例子来区分各种constructor。copy constructor就好像是你拿了一个具体的物品并且对店员桑说“要一个跟这个一摸一样的”,这样就得到了一个新的物品。注意:你新获得一个object,而copy assignment是不产生新的object。
2.为什么需要copy assignment?
跟copy constructor一样,copy assignment operator是由默认的,做的同样是按位拷贝(bit-wise),即浅拷贝(shallow copy)
unpleasant effects:
Changes via a can be observed via b.
Once b is destroyed, a.name is a dangling pointer.
If a is destroyed, deleting the dangling pointer yields undefined behavior.
Since the assignment does not take into account what name pointed to before the assignment, sooner or later you will get memory leaks all over the place.
3.实现方式
(quote from stackoverflow)
dumb_array& dumb_array:: operator=(const dumb_array& other)
{
if (this != &other)
{
delete[]mArray;
mArray = nullptr;
msize = other.msize;
mArray = msize ? new int[msize] : nullptr;
copy(other.mArray, other.mArray + msize, mArray);
}
return *this;
}
MyStr& MyStr::operator=(const MyStr&other)
{
if(this!=&other)
if(name!=NULL)
{
delete[]name;
int len=strlen(other.name);
name=new char[len+1];
strcpy_s(this.name,strlen(other.name)+1,other.name);
}
return *this;
}
tips:
- 检查是否是self-assignment(防止删除了source string)
- 检查对象是否为空,delete NULL会引发前文所说的dangling pointer等undefined behavior
- delete[] 对应new[]
- 注意strlen的使用,+1不要忘了
- strcpy_s第二个参数是source string的size(i.e. length+1)
でも 读者不妨想想这样是否就万无一失了呢?
mArray = msize ? new int[msize] : nullptr;
If new int[mSize]
fails, *this
will have been modified. (Namely, the size is wrong and the data is gone!)
dumb_array& operator=(const dumb_array& other)
{
if (this != &other) // (1)
{
// get the new data ready before we replace the old
std::size_t newSize = other.mSize;
int* newArray = newSize ? new int[newSize]() : nullptr; // (3)
std::copy(other.mArray, other.mArray + newSize, newArray); // (3)
// replace the old data (all are non-throwing)
delete [] mArray;
mSize = newSize;
mArray = newArray;
}
return *this;
}
区别在于我们是先删除数据还是先得到新的数据
就好像交换人质,是愿意先把东西给出去呢还是先从对方手里拿到自己想要的(当然选后者啦> <)