稍后设置std :: shared_ptr源

时间:2013-06-08 23:11:05

标签: c++ shared-ptr smart-pointers

我刚开始使用C ++并试图了解智能指针。显然,下面的代码会崩溃(我想这是因为赋值创建了shared_ptr的副本?)。有没有办法通过在foo.Other上调用某种设置方法来更新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;
}

编辑: 这是我得到的例外,因为它指向null:

  

Test.exe中0x01219AEF处的第一次机会异常:0xC0000005:访问冲突读取位置0x00000000。   Test.exe中0x01219AEF处的未处理异常:0xC0000005:访问冲突读取位置0x00000000。

2 个答案:

答案 0 :(得分:5)

你似乎认为这样做:

foo.Other = ptrs[3];

在两个对象之间创建某种关系,这样如果你改变其中一个,那么另一个也会改变。

这不是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 );

但是shared_ptr对象本身并不都是彼此相同的副本。

他们指向同样的事情,这并不意味着他们 是同一件事。

如果您将ptrs[3]更改为指向不同的内容而使foo.Other指向不同的内容。如果这样做会使shared_ptr几乎无用,你就无法拥有一个对象的多个所有者,因为只要其中一个人停止拥有该对象,所有其他人就会停止拥有它并且它将被销毁

相反,只有您更新的shared_ptr获得新值,而其他shared_ptr则保留旧值。

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 );

答案 1 :(得分:4)

shared_ptr和其他内容无关,您的所有代码归结为:

int a = 0;
int b = a;
a = 42;
// why b isn't == to 42?

考虑一下......我担心这是我能提供的答案。

请不要犹豫要求澄清,我很乐意回答,但在你做之前,请再次考虑