1

I'm just starting out with C++ and trying to get my head around smart pointers. Obviously, the following code will crash (I suppose it's because the assignment created a copy of the shared_ptr?). Is there a way to keep foo.Other updated by calling some kind of set method on 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;
}

Edit: This is the exception I'm getting since it's pointing to null:

First-chance exception at 0x01219AEF in Test.exe: 0xC0000005: Access violation reading location 0x00000000. Unhandled exception at 0x01219AEF in Test.exe: 0xC0000005: Access violation reading location 0x00000000.

4

2 回答 2

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 );
于 2013-06-08T23:58:26.003 回答
4

与其他东西无关shared_ptr,您的所有代码都归结为:

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

想一想……恐怕这就是我能提供的答案。

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

于 2013-06-08T23:26:38.960 回答