shared_ptr<T>如何检测T是否派生自enable_shared_from_this<T>?

3
我正在尝试从零开始实现 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分配给内部存储的弱引用。

是啊,怎么做到的呢?

2个回答

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

有几个版本的 sp_enable_shared_from_this。选择哪个版本取决于 Y 是否继承了 enable_shared_from_this


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
}

为什么仅拥有 template <class Z> magic_construct(enable_shared_from_this<Z>* share) 是不够的?我为什么需要 sprp 参数? - Alex
私有继承会发生什么? - curiousguy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接