shared_ptr如何<T>检测 T 源自enable_shared_from_this<T>?



我正试图通过从头开始实现shared_ptr来学习它是如何工作的,但我不知道如何检测t的基类。

我尝试过使用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++的实现对我来说太令人困惑了,我正在寻找一个简单的解释。

这里写着

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

是的,怎么做?

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

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
}

一个选项是使其基于函数模板重载。

以下是一个简化的解决方案:我们有两个班A和B。函数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 );

CCD_ 2有几个版本。基于Y是否源自enable_shared_from_this而选择的版本。

相关内容

  • 没有找到相关文章

最新更新