说,我有一个shared_ptr<A> ptrFirst
,它已初始化并指向内存中的某个对象。现在,我这样定义一个新的shared_ptr
:
shared_ptr<A> ptrSecond = make_shared<A>(ptrFirst.get());
我知道我可以使用简单的分配来防止任何问题。但是我想知道是否以这种方式定义ptrSecond,对于同一个对象,我是否会有两个不同的控制块?这甚至不好吗?
答案 0 :(得分:3)
除非您有一个将A*
作为唯一参数的构造函数,否则您的行将不会进行事件编译。
如果您确实有构造函数A::A(A*)
,那么make_shared
将创建一个新对象-很好。
如果要改用std::shared_ptr
构造函数:
std::shared_ptr<A> ptrSecond = std::shared_ptr<A>(ptrFirst.get());
那是个问题。这将导致双重释放,即UB。
答案 1 :(得分:2)
但是我想知道是否以这种方式定义ptrSecond,对于同一个对象,我是否会有两个不同的控制块?
不。这段代码:
shared_ptr<A> ptrSecond = make_shared<A>(ptrFirst.get());
在逻辑上等于:
shared_ptr<A> ptrSecond( new A( ptrFirst.get() ) );
因此,基本上它将创建A
的新实例并使用指向另一个A
的指针对其进行初始化,当然,只有在定义了正确的ctor的情况下,它才会编译。
这甚至很糟糕吗?
如果您这样说:
shared_ptr<A> ptrSecond( ptrFirst.get() );
是的,这很不好,因为双重分配会导致UB。