我有一个对象(Z),它来自另外两个对象(A和B)。
A和B分别来自enable_shared_from_this<>
enable_shared_from_this<A>
和enable_shared_from_this<B>
。
当然我在Z上调用shared_from_this()
。当然编译器报告这是不明确的。
我的问题是:
enable_shared_from_this<>
继承两次是安全的,还是会创建两个分开的引用计数(不好!)注意:
我发现了另一个问题bad weak pointer when base and derived class both inherit from boost::enable_shared_from_this,但它并没有真正回答。我也应该使用virtual
技巧吗?
答案 0 :(得分:13)
是的,根据bad weak pointer when base and derived class both inherit from boost::enable_shared_from_this,解决方案是使用虚拟继承。这是C ++ 11标准shared_ptr
(不是Boost)的实现:
#include <memory>
struct virtual_enable_shared_from_this_base:
std::enable_shared_from_this<virtual_enable_shared_from_this_base> {
virtual ~virtual_enable_shared_from_this_base() {}
};
template<typename T>
struct virtual_enable_shared_from_this:
virtual virtual_enable_shared_from_this_base {
std::shared_ptr<T> shared_from_this() {
return std::dynamic_pointer_cast<T>(
virtual_enable_shared_from_this_base::shared_from_this());
}
};
struct A: virtual_enable_shared_from_this<A> {};
struct B: virtual_enable_shared_from_this<B> {};
struct Z: A, B { };
int main() {
std::shared_ptr<Z> z = std::make_shared<Z>();
std::shared_ptr<B> b = z->B::shared_from_this();
}
这可能不是默认实现的一部分,可能是因为虚拟继承的开销。
答案 1 :(得分:1)
是的,你的班级将来自两个不同的班级enable_shared_from_this<A>
和enable_shared_from_this<B>
,并且有两个不同的弱参考
由于虚拟继承
,该答案的诀窍允许有一个基类答案 2 :(得分:0)
使用shared_ptr
别名构造函数,可以得出ecatmur答案的变体:
#include <memory>
struct virtual_enable_shared_from_this_base:
std::enable_shared_from_this<virtual_enable_shared_from_this_base> {
virtual ~virtual_enable_shared_from_this_base() {}
};
template<typename T>
struct virtual_enable_shared_from_this:
virtual virtual_enable_shared_from_this_base {
std::shared_ptr<T> shared_from_this() {
return std::shared_ptr<T>(
virtual_enable_shared_from_this_base::shared_from_this(),
static_cast<T*>(this));
}
std::shared_ptr<const T> shared_from_this() const {
return std::shared_ptr<const T>(
virtual_enable_shared_from_this_base::shared_from_this(),
static_cast<const T*>(this));
}
};
struct A: virtual_enable_shared_from_this<A> {};
struct B: virtual_enable_shared_from_this<B> {};
struct Z: A, B { };
int main() {
std::shared_ptr<Z> z = std::make_shared<Z>();
std::shared_ptr<B> b = z->B::shared_from_this();
}
我希望该版本在许多情况下都可以更快,因为它避免了昂贵的动态转换。但是,像往常一样,只有becnhmarks具有最后的词。另外,我添加了const
变体。