为什么在使用复制分配运算符时需要删除资源?
Why do I need to delete resources when using copy-assign operator?
例如我的一本书中的代码:
class HasPtr {
public:
HasPtr(const HasPtr& h): ps(new std::string(*h.ps)), i(h.i) { }
HasPtr(const std::string &s = std::string()): ps(new std::string(s)), i(0) { }
HasPtr& operator=(const HasPtr&);
~HasPtr() { delete ps; }
private:
std::string *ps;
int i;
};
HasPtr& HasPtr::operator=(const HasPtr &rhs){
auto newp = new string(*rhs.ps); // copy the underlying string
delete ps; // free the old memory
ps = newp; // copy data from rhs into this object
i = rhs.i;
return *this; // return this object
}
似乎 operator= 的内部可能只是:
*ps = *rhs.ps
i = rhs.i
return *this;
不需要先删除指针,这样做似乎是多余的。它确实提到它是以一种方式编写的,以便在发生异常但没有泄露过去时使对象处于合适的状态,但我看不出会发生什么异常,即使我的替代方法也无法处理。为什么要先删除对象再赋值?
在这种情况下,是的,那很好。
您没有泄露动态分配的字符串:您正在重新使用它。
我觉得这很好。
你是对的,std::string
赋值 already 提供了强大的异常保证,因此如果在复制字符串时发生异常,你仍会将对象保留在其原始状态。
当然没有理由像那样分配一个std::string
和new
。你可以这样写:
class HasNoPtr {
public:
HasNoPtr(const std::string& s): ps(s), i(0) { }
private:
std::string ps;
int i;
};
例如我的一本书中的代码:
class HasPtr {
public:
HasPtr(const HasPtr& h): ps(new std::string(*h.ps)), i(h.i) { }
HasPtr(const std::string &s = std::string()): ps(new std::string(s)), i(0) { }
HasPtr& operator=(const HasPtr&);
~HasPtr() { delete ps; }
private:
std::string *ps;
int i;
};
HasPtr& HasPtr::operator=(const HasPtr &rhs){
auto newp = new string(*rhs.ps); // copy the underlying string
delete ps; // free the old memory
ps = newp; // copy data from rhs into this object
i = rhs.i;
return *this; // return this object
}
似乎 operator= 的内部可能只是:
*ps = *rhs.ps
i = rhs.i
return *this;
不需要先删除指针,这样做似乎是多余的。它确实提到它是以一种方式编写的,以便在发生异常但没有泄露过去时使对象处于合适的状态,但我看不出会发生什么异常,即使我的替代方法也无法处理。为什么要先删除对象再赋值?
在这种情况下,是的,那很好。
您没有泄露动态分配的字符串:您正在重新使用它。
我觉得这很好。
你是对的,std::string
赋值 already 提供了强大的异常保证,因此如果在复制字符串时发生异常,你仍会将对象保留在其原始状态。
当然没有理由像那样分配一个std::string
和new
。你可以这样写:
class HasNoPtr {
public:
HasNoPtr(const std::string& s): ps(s), i(0) { }
private:
std::string ps;
int i;
};