在后期设置std::shared_ptr源

Setting std::shared_ptr source at a later stage

本文关键字:shared ptr std 设置      更新时间:2023-10-16

我刚开始学习c++,并试图了解智能指针。显然,下面的代码会崩溃(我想这是因为赋值创建了shared_ptr的副本)。是否有一种方法可以通过在ptrs[3]上调用某种set方法来保持foo.Other的更新?

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.

您似乎认为这样做:

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

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

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

好好想想……恐怕这就是我所能提供的答案了。

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