使用copy-assign运算符时,为什么需要删除资源?

时间:2015-08-27 23:44:05

标签: c++ delete-operator copy-assignment

例如,我的一本书中的代码如下:

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
}

似乎是运营商的内部=可能只是:

*ps = *rhs.ps
i = rhs.i
return *this;

首先不需要删除指针,这似乎是多余的。它确实提到它的编写方式是在异常发生时将对象保持在合适的状态,但没有透露过,但我不知道即使我的替代方案也不会发生什么异常。处理为什么在分配之前需要先删除对象?

2 个答案:

答案 0 :(得分:5)

在这种情况下,是的,那没关系。

您没有泄漏动态分配的字符串:您正在重新使用它。

答案 1 :(得分:4)

这对我来说很好看。

你是对的,std::string赋值already提供强大的异常保证,因此如果复制字符串发生异常,你仍然会将对象保持原始状态。

当然没有理由像这样std::string分配new。你可以写一下:

class HasNoPtr {
public:
    HasNoPtr(const std::string& s): ps(s), i(0) { }
private:
    std::string ps;
    int i;
};