扩展 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;
}
};
因此,其意图是struct A
公开继承enable_shared_from_this_virtual<A>
并struct B
公开继承enable_shared_from_this_virtual<B>
. 由于它们都共享相同的公共虚拟对象,因此层次结构中只有一个std::enable_shared_from_this
。
当您调用任一 classesshared_from_this
时,它执行从enable_shared_from_this_virtual<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;
}