shared_ptr <t>如何检测T派生自enable_shared_from_this <t>?</t> </t>

时间:2014-10-11 17:39:02

标签: c++ boost std shared-ptr

我试图从头开始实现shared_ptr的工作方式,而我无法弄清楚如何检测T&#39的基类。

我尝试过使用is_base_of(),但这会给出一个const值,我可以使用if语句来设置对象的内部weak_ptr。

我正在思考这些问题:

template <class T>
class shared_ptr
{
    shared_ptr(T* ptr)
    {
        ...
    }

    shared_ptr(enable_shared_from_this<T>* ptr)
    {
        ...

        Ptr->m_this = weak_ptr<T>(this);
    }
};

但到目前为止没有运气。 Boost和VC ++实现对我来说太混乱了,我正在寻找一个简单的解释。

Here它说

  

std :: shared_ptr的构造函数检测到enable_shared_from_this base的存在,并将新创建的std :: shared_ptr分配给内部存储的弱引用。

是的,怎么样?

2 个答案:

答案 0 :(得分:1)

一种选择是基于功能模板重载来实现它。

这是一个简化的解决方案: 我们有两个A和B类.A类来自H. 函数is_derived_from_h被重载,可用于检测某些类X是否来自H。

#include <stdlib.h>
#include <iostream>

class H {};
class A: public H {};
class B {};

// (1)
template <typename X>
void is_derived_from_h(X* px, H* ph) {
  std::cout << "TRUE" << std::endl;
}

// (2)
void is_derived_from_h(...) {
  std::cout << "FALSE" << std::endl;
}

int main(int argc, char* argv[]) {

  A* pa = new A;
  B* pb = new B;

  is_derived_from_h(pa, pa); // (1) is selected, the closest overload
  is_derived_from_h(pb, pb); // (2) is selected, (1) is not viable

  delete pa;
  delete pb;

  return EXIT_SUCCESS;
}

输出:

TRUE
FALSE

如果是Boost,请跟踪以下呼叫:

shared_ptr( Y * p )
->
boost::detail::sp_pointer_construct( this, p, pn );
  ->
boost::detail::sp_enable_shared_from_this( ppx, p, p );

Threre是sp_enable_shared_from_this的几个版本。根据Y是否来自enable_shared_from_this而选择的版本。

答案 1 :(得分:1)

简单 - 使用模板参数推导!这是解决所有世界问题的方法,但你已经知道了:)基于boost方式的解决方案解决了你的问题如下。我们创建了一个模板化的辅助类,它实际上处理了构造的细节。

template <class T>
class shared_ptr
{
    shared_ptr(T* ptr)
    {
        magic_construct(this, ptr, ptr);
    }
};

template <class X, class Y, class Z>
void magic_construct(shared_ptr<X>* sp, Y* rp, enable_shared_from_this<Z>* shareable)
{
//Do the weak_ptr handling here
}

void magic_construct(...)//This is the default case
{
//This is the case where you have no inheritance from enable_shared_from_this
}
相关问题