gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:01:54 27 4
gpt4 key购买 nike

我是 C++ 初学者。我正在做 C++ Primer(第 5 版)中的练习。我找到了一个引用来自 Github ( Here ) 的练习 13.8,如下所示。

#include <string>
#include <iostream>

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;,保留有什么好处。

最佳答案

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

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

请注意,在现代 C++ 中,您应该几乎永远不要使用newdelete 来管理这样的对象。请改用智能指针,例如std::unique_ptrstd::shared_ptr ,它会安全方便地为您管理内存。

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

作为Jan Hudec在评论中提到,将 std::string 存储在堆上通常很愚蠢 - std::string 是堆分配的字符数组的包装器,它已经为你管理了内存。

关于c++ - 为什么在复制赋值运算符的定义中需要删除?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34652792/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com