enable_shared_from_this的双重继承
Double inheritance of enable_shared_from_this
我有一个对象(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<>
继承两次是否安全,还是创建两个分开的引用计数(错误!( - 如果不安全,我该如何解决
注:当基类和派生类都从boost::enable_shared_from_this继承时,我发现另一个问题是坏的弱指针,但它并没有真正回答。我也应该使用virtual
技巧吗?
是的,根据坏的弱指针,当基类和派生类都继承自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();
}
这不是默认实现的一部分,可能是因为虚拟继承的开销。
是的,您的类将从两个不同的类enable_shared_from_this<A>
和enable_shared_from_this<B>
派生,并具有两个不同弱ref的
这个答案的诀窍是允许有一个基类,因为虚拟继承
使用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();
}
我预计这个版本在很多情况下会更快,因为它避免了代价高昂的动态转换。然而,和往常一样,只有基准才有最终决定权。此外,我还添加了const
变体。
相关文章:
- 表示"accepting anything for this template argument" C++概念的通配符
- 继承函数的重载解析
- 为什么使用 "this" 指针调用派生成员函数?
- 继承期间显示未知行为的子类
- 头文件-继承c++
- 为什么在保护模式下继承升级不起作用
- 通过继承类使用来自不同命名空间的运算符
- 关于C++中具有多重继承"this"指针的说明
- C++ 中的构造函数、继承、堆栈、堆、this-pointer 和段错误
- "Attribute is protected within this context"继承和 .h 和.cpp文件
- GCC:当层次结构中存在虚拟继承时,C++11 内联对象初始化(使用 "this")不起作用
- 通过将指向"this"的指针传递给基构造函数来消除C++菱形继承
- "<varName> was not declared in this scope" C++中使用模板和继承
- 访问修饰符在继承中的不同行为取决于"this"关键字和模板或缺少它们
- MinGW 4.7.0 到 4.7.2 错误:使用混合虚拟和非虚拟多重继承时成员函数中的"this"指针无效
- 多重继承和this指针
- 继承返回*this的成员函数
- 模板和继承"not declared in this scope"错误
- 方法的C++继承,但返回类型错误(自动转换?typeid(*this)?)
- C++ 虚拟继承:在派生的初始值设定项列表中static_cast "this"虚拟父级