sch*_*lig 1 c++ smart-pointers shared-ptr
我刚刚开始使用C++并试图了解智能指针.显然,下面的代码会崩溃(我想这是因为赋值创建了shared_ptr的副本?).有没有办法foo.Other通过调用某种set方法来保持更新ptrs[3]?
class Foo
{
public:
int X;
std::shared_ptr<Foo> Other;
Foo() : X(10) { }
};
int main()
{
Foo foo;
std::vector<std::shared_ptr<Foo>> ptrs(10);
foo.Other = ptrs[3];
std::shared_ptr<Foo> other = std::shared_ptr<Foo>(new Foo());
ptrs[3] = other;
std::cout << foo.Other->X << std::endl; // throws Access violation exception
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编辑:这是我得到的异常,因为它指向null:
Test.exe中0x01219AEF处的第一次机会异常:0xC0000005:访问冲突读取位置0x00000000.Test.exe中0x01219AEF处的未处理异常:0xC0000005:访问冲突读取位置0x00000000.
你似乎有这样的印象:
foo.Other = ptrs[3];
Run Code Online (Sandbox Code Playgroud)
在两个对象之间创建某种关系,这样如果你改变其中一个,那么另一个也会改变.
那不是多么shared_ptr有效.它指向的东西是共享的,并且改变那个东西意味着它的所有指针都会看到更改的值(因为只有一个值,它由多个对象拥有)所以这适用:
std::shared_ptr<int> p = std::make_shared<int>(1);
assert( *p == 1 );
std::shared_ptr<int> q = p;
*q = 2;
assert( *p == 1 );
Run Code Online (Sandbox Code Playgroud)
但是shared_ptr对象本身并不都是彼此相同的副本.
他们指向同一件事,这并不意味着他们是同一件事.
如果你改变ptrs[3]指向不同的东西,也不会foo.Other指出不同的东西.如果这样做会使得shared_ptr几乎无用,你就无法有一个对象的多个所有者,因为只要其中一个人停止拥有该对象,所有其他人就会停止拥有它并且它将被销毁.
相反,只有shared_ptr你更新获得一个新值,其他shared_ptrs保持旧值.
std::shared_ptr<int> p = std::make_shared<int>(1);
assert( *p == 1 );
std::shared_ptr<int> q = p;
assert( *q == 1 );
assert( p == q );
assert( p.get() == q.get() );
assert( *p == *q );
p = std::make_shared<int>(2);
assert( *p == 2 );
assert( *q == 1 );
assert( p != q );
assert( p.get() != q.get() );
assert( *p != *q );
Run Code Online (Sandbox Code Playgroud)