【发布时间】:2015-10-18 06:14:30
【问题描述】:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class HasPtr{
public:
//constructor accepts a string
HasPtr(const string &s = string()) : ps(new string(s)), i(0), use(new size_t(1)) {}
//copy constructor
HasPtr(const HasPtr &h) : ps(h.ps), i(h.i), use(h.use) { ++*use; }
//copy assignment operator
HasPtr &operator=(const HasPtr &h)
{
++*h.use;
if(--*use == 0)
{
delete ps;
delete use;
}
ps = h.ps;
i = h.i;
use = h.use;
return *this;
}
~HasPtr()
{
if(--*use == 0)
{
delete ps;
delete use;
}
}
//private:
string *ps;
int i;
size_t *use;
};
int main()
{
HasPtr h("hi mom");
HasPtr h2 = h;
HasPtr h3("hi dad");
h2 = h3;
cout << "h: " << *h.ps << endl;
cout << "h2: " << *h2.ps << endl;
cout << "h3: " << *h3.ps << endl;
}
输出为:
h: hi mom
h2: hi dad
h3: hi dad
我认为输出应该是:
h: hi dad
h2: hi dad
h3: hi dad
我认为输出应该如上的原因:
h 是“嗨妈妈”,h2 共享 h1,所以 h2 是“嗨妈妈”,h3 是“嗨爸爸”,我认为 h2 = h3 更改了 h1 或者因为 h2 共享 h1,但事实并非如此。
我做错了什么?
【问题讨论】:
-
What am I doing wrong?:使用指针。如果你使用对象,这一切都会消失。还有一个引用计数的智能指针std::shared_ptr -
h2 = h3根本不影响h1。您不是在修改指向的内容,而是存储在h2中的指针。比较:coliru.stacked-crooked.com/a/c380c6c80e66a393 -
为了将来参考,您可能想了解copy and swap idiom 和the Big Three。正如@LokiAstari 所说,您可能还只想使用内置的
std::shared_ptr。 -
h2 共享 h1,直到您分配给 h2 为止。这是经典的引用计数 - 语义就像您在处理简单的值对象一样,但副本被推迟到真正需要它们时。一个好主意,但在实践中并不是一个胜利,特别是如果您使用多个线程。