鉴于此类是 enable_shared_from_this :
class connection : public std::enable_shared_from_this<connection>
{
//...
};
假设我从相同的 std::shared_ptr
创建了两个connection*
实例,如下所示:
std::shared_ptr<connection> rc(new connection);
std::shared_ptr<connection> fc(rc.get(), [](connection const * c) {
std::cout << "fake delete" << std::endl;
});
到目前为止它很好,因为资源{connection*
}归单 shared_ptr
- rc
所有,而且fc
只是有一个假的删除者。
之后,我这样做:
auto sc = fc->shared_from_this();
//OR auto sc = rc->shared_from_this(); //does not make any difference!
现在哪个shared_ptr
- rc
或fc
- 会sc
与引用计数共享?换句话说,
std::cout << rc->use_count() << std::endl;
std::cout << fc->use_count() << std::endl;
这些印刷品应该是什么?我测试了此代码,而found rc
似乎只有2
引用fc
只有1
。
我的问题是,为什么?什么应该是正确的行为及其理由?
我正在使用C ++ 11和GCC 4.7.3 。
答案 0 :(得分:1)
原始指针重载假定指向对象的所有权。因此,使用已由shared_ptr管理的对象(例如
shared_ptr(ptr.get())
)的原始指针重载构造shared_ptr可能会导致未定义的行为,即使该对象是从{{1 }}。 - http://en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr
在您的情况下,您将获得具有两个不同所有权信息块的共享指针,但总是递增该类的第一个共享指针实例的引用计数。
如果你删除了假冒删除者&#39;你得到双重免费问题。
答案 1 :(得分:0)
我们唯一知道的是:
[util.smartptr.enab] shared_from_this();:
要求: enable_shared_from_t这应该是T的可访问基类。*这应该是T类型的对象t的子对象。应该至少有一个拥有的shared_ptr实例p &安培;吨强>
返回:与p。
共享所有权的shared_ptr对象r后置条件: r.get()== this。
如果按字面意思读取,暗示如果fc-&gt; shared_from_this()返回rc
或fc
的副本,则未指定(虽然理智的实现只会分配给内部weak_ptr一次,因此行为应该与c ++ 17中的行为相同,正如您所观察到的那样。)
情况很明显:enable_shared_from_this
基本上是weak_ptr
,由第一个shared_ptr
构造函数(或make_shared
工厂)分配,它看到它处于过期状态。
因此,rc
设置weak_ptr
,fc
不设置,fc->shared_from_this()
返回rc
的副本。只要所有fc.get()
副本都被销毁,rc
就会返回一个僵尸指针。 您观察到的行为是正确的。
请注意,所有采用非空指针(最多是删除器和/或分配器)的shared_ptr构造函数将拥有指针并管理其生命周期,就好像它是重新构造的一样,唯一的区别是只有第一个将分配给enable_shared_from_this的weak_ptr,如果有的话。