提升shared_from_this和多重继承

Chr*_*son 13 c++ multiple-inheritance shared-ptr enable-shared-from-this

我在使用boost enable_shared_from_this和多重继承时遇到了一些麻烦.

该场景可以描述如下:

  1. A实现了一些功能,应该继承enable_shared_from_this

  2. B实现了另一个功能,应该继承enable_shared_from_this

  3. DAB(class D : public A, public B {})继承功能

  4. 当我B从类中使用一些类功能时,D我得到了一个异常(bad_weak_ptr)

  5. 继承enable_shared_from_this课程D对我来说不是一个选择

我不知道如何解决这个问题.

哦,我正在使用Visual C++ 2010.

Dav*_*e S 8

扩展Potatoswatter的解决方案,如果你可以改变A和B使用与enable_shared_from_this略有不同的东西.代码使用标准库版本,但boost实现应该类似.说明如下

#include <memory>
template<typename T>
struct enable_shared_from_this_virtual;

class enable_shared_from_this_virtual_base : public std::enable_shared_from_this<enable_shared_from_this_virtual_base>
{
    typedef std::enable_shared_from_this<enable_shared_from_this_virtual_base> base_type;
    template<typename T>
    friend struct enable_shared_from_this_virtual;

    std::shared_ptr<enable_shared_from_this_virtual_base> shared_from_this()
    {
        return base_type::shared_from_this();
    }
    std::shared_ptr<enable_shared_from_this_virtual_base const> shared_from_this() const
    {
       return base_type::shared_from_this();
    }
};

template<typename T>
struct enable_shared_from_this_virtual: virtual enable_shared_from_this_virtual_base
{
    typedef enable_shared_from_this_virtual_base base_type;

public:
    std::shared_ptr<T> shared_from_this()
    {
       std::shared_ptr<T> result(base_type::shared_from_this(), static_cast<T*>(this));
       return result;
    }

    std::shared_ptr<T const> shared_from_this() const
    {
        std::shared_ptr<T const> result(base_type::shared_from_this(), static_cast<T const*>(this));
        return result;
    }
};
Run Code Online (Sandbox Code Playgroud)

因此,意图是,struct A将来自公开继承enable_shared_from_this_virtual<A>struct B会从公开继承enable_shared_from_this_virtual<B>.由于它们共享相同的公共虚拟对象,因此std::enable_shared_from_this层次结构中只有一个.

当您调用任何一个类时shared_from_this,它会执行从enable_shared_from_this_virtual<T>*T*转换为T*,并使用shared_ptr的别名构造函数,以便新的shared_ptr指向T*并与单个共享指针共享所有权.

在顶部使用朋友是为了防止任何人直接访问虚拟基地的shared_from_this()成员.他们必须通过提供的enable_shared_from_this_virtual<T>.

一个例子:

#include <iostream>

struct A : public enable_shared_from_this_virtual<A>
{
    void foo()
    {
        shared_from_this()->baz();
    }

    void baz()
    {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
    }
};

struct B : public enable_shared_from_this_virtual<B>
{
    void bar()
    {
        shared_from_this()->baz();
    }

    void baz()
    {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
    }
};

struct D: A, B {};


int main()
{
 std::shared_ptr<D> d(new D);
 d->foo();
 d->bar();
 return 0;
}
Run Code Online (Sandbox Code Playgroud)


Jon*_*ely 2

shared_from_this该标准对于如何实现有点模糊,但所有实现似乎都是一致的,因为 Boost 提供了参考实现。

当您创建构造boost::shared_ptr<D> myD(new D())函数时,检查某些对象shared_ptr是否存在从D*到的明确转换(这意味着具有类型 的基类)。如果转换有效,则基类中的 a 将被设置为引用新创建的.enable_shared_from_this<X>*XDenable_shared_from_this<X>weak_ptr<X>shared_ptr

在您的代码中,有两种可能的转换, toenable_shared_from_this<A>enable_shared_from_this<B>,这是不明确的,因此没有weak_ptr设置为引用myDB这意味着如果稍后调用一个成员函数,shared_from_this()它将得到一个bad_weak_ptr异常,因为它的enable_shared_from_this<B>成员从未设置过。