为什么我们需要delete语句?
const MyString& operator=(const MyString& rhs)
{
if (this != &rhs) {
delete[] this->str; // Why is this required?
this->str = new char[strlen(rhs.str) + 1]; // allocate new memory
strcpy(this->str, rhs.str); // copy characters
this->length = rhs.length; // copy length
}
return *this; // return self-reference so cascaded assignment works
}发布于 2011-07-17 16:16:18
这不是复制构造函数,它是赋值运算符。您需要删除,因为要分配的对象已保存以前的值。
这段代码也不是很好,因为首先删除旧值,然后分配新值……但分配可能会抛出异常,在这种情况下,对象将保留一个指向已释放区域的指针。一种更好的方法是先分配,然后删除旧值(永远不允许异常从析构函数中转义...see this link for an explanation),因此分配要么成功,要么失败,不会影响任何东西。
一种常见的习惯用法是实现一个复制构造函数和一个交换操作(交换两个实例的内容,以保证不会抛出异常)。然后实现assignment operator combining the two...从异常处理的角度来看,这既需要更少的代码,又是健壮的。
发布于 2011-07-17 16:51:15
答案是你必须释放内存,因为如果你没有释放内存,那么它就会丢失,因为你正在为新的分配重用指针。无论如何,如果你正在学习运算符,通常会以复制构造+无抛出交换的方式编写operator=:
class MyString {
char* str;
int len;
public:
MyString( const MyString& rhs ) : str( new char[ rhs.len ] ), len( rhs.len ) {
memcpy( str, rhs.str, len );
}
~MyString() {
delete str;
}
friend void swap( MyString & lhs, MyString & rhs ) throw() {
using std::swap;
swap( lhs.str, rhs.str );
swap( lhs.len, rhs.len );
}
MyString& operator=( MyString rhs ) { //note: by value
swap( *this, rhs );
return *this;
}
};请注意,执行的操作是相似的。现在的区别是:
发布于 2011-07-17 16:16:17
这不是复制构造函数。这只是一个复制操作符。所以这个->str将指向以前分配的内存。如果在这个->字符串被赋予新值之前没有释放内存,那么它将永远不会被释放,因为它唯一引用已经被覆盖。因此,如果没有delete语句,该方法将泄漏内存。
https://stackoverflow.com/questions/6722643
复制相似问题