当前位置:  开发笔记 > 编程语言 > 正文

为什么在复制赋值运算符的定义中需要删除?

如何解决《为什么在复制赋值运算符的定义中需要删除?》经验,为你挑选了1个好方法。

我是C++初学者.我正在使用C++ Primer(第5版)进行练习.我从Github(这里)找到了对练习13.8的引用,如下所示.

#include 
#include 

using std::cout;
using std::endl;

class HasPtr {
public:
    HasPtr(const std::string &s = std::string()) : ps(new std::string(s)), i(0) { }
    HasPtr(const HasPtr &hp) : ps(new std::string(*hp.ps)), i(hp.i) { }
    HasPtr& operator=(const HasPtr &hp) {
        std::string *new_ps = new std::string(*hp.ps);
        delete ps;          // I don't know why it is needed here? 
                            // But when I delete this line, it also works.
        ps = new_ps;
        i = hp.i;
        return *this;
    }

    void print() {
        cout << *(this->ps) << endl;
        cout << this->i << endl;
    }

private:
    std::string *ps;
    int i;
};

int main() {
    HasPtr hp1("hello"), hp2("world");
    hp1.print();
    hp1 = hp2;
    cout << "After the assignment:" << endl;
    hp1.print();
}

令我困惑的是HasPtr& operator=(const HasPtr &hp)功能.我不知道为什么delete ps;需要这里.我认为这是一个错误,但是在编译代码时它起作用了.但是,当我删除行时,它也有效delete ps;.所以,我不知道是否delete ps;需要,如果保留它有什么好处.



1> Vittorio Rom..:

HasPtr::ps是堆分配的std::string指针.

new在所有HasPtr构造函数中使用分配和构造.因此,当HasPtr::ps被另一个堆分配的指针替换时,必须释放现有内存delete以避免内存泄漏.

请注意,在现代C++中,您几乎不应该使用newdelete管理这样的对象.使用智能指针,比如std::unique_ptr或者std::shared_ptr,安全方便地为您完成内存管理.

我仍然建议熟悉new并且delete,因为大量现有代码使用它们.cppreference.com是查找有关该语言的详细信息的好地方.

正如Jan Hudec在评论中提到的那样,std::string在堆上存储一般是非常愚蠢的 - std::string是一个堆分配字符数组的包装器,它已经为你管理了内存.


我想补充一点,即使通过智能指针,堆分配字符串在大多数情况下也是愚蠢的.std :: string最适合作为值类型.
推荐阅读
地之南_816
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有