我是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;
需要,如果保留它有什么好处.
HasPtr::ps
是堆分配的std::string
指针.
它new
在所有HasPtr
构造函数中使用分配和构造.因此,当HasPtr::ps
被另一个堆分配的指针替换时,必须释放现有内存delete
以避免内存泄漏.
请注意,在现代C++中,您几乎不应该使用new
和delete
管理这样的对象.使用智能指针,比如std::unique_ptr
或者std::shared_ptr
,安全方便地为您完成内存管理.
我仍然建议熟悉new
并且delete
,因为大量现有代码使用它们.cppreference.com
是查找有关该语言的详细信息的好地方.
正如Jan Hudec在评论中提到的那样,std::string
在堆上存储一般是非常愚蠢的 - std::string
是一个堆分配字符数组的包装器,它已经为你管理了内存.