C++:CRTP 析构函数
C++ : CRTP destructor?
在一个项目中,我有以下问题:
我有一个非常简单的继承方案(我需要继承而不是组合):
类基础
->类派生A
->类 衍生分贝
->类派生C
A,B和C派生自Base,仅此而已。所以现在我有 2 个选择:
虚拟的公共继承
没有虚拟的私人继承
出于某些优化原因(我需要很多内联)我不想要虚拟性......而且我不想要私人继承。我认为剩下的唯一选择是 CRTP。但是基类有大约 300 个函数,在其中实现 CRTP 将是一个真正的痛苦。
所以我想知道以下解决方案是否有效:我只在基类的析构函数中使用 CRTP:
template<class TCRTP> class Base
{
~Base() {delete static_cast<TCRTP*>(this);}
}
其中 TCRTP 将是派生 A、B 或 C,我做公共继承。是完全可以的,还是有问题的?
谢谢。
你的析构函数肯定是错误的。类的析构函数不会也不得delete
对象的内存。
你反对没有虚函数的公共继承是什么?(至少)有几种方法可以防止某人通过基指针意外删除派生对象。一种是使基本析构函数protected
。
另一种方法是将派生类的动态分配实例直接填充到shared_ptr
中。这甚至可以是一个shared_ptr<Base>
:
std::shared_ptr<Base> foo(new DerivedA(...));
由于shared_ptr
有一个捕获其参数类型的模板构造函数,因此Base*
指针将在与shared_ptr
关联的删除器函数中转换为DerivedA*
,从而正确删除。没有人应该愚蠢到试图从shared_ptr
中提取指针并将其删除为Base*
。
当然,如果你没有虚函数,那么只有当派生类之间的唯一区别是它们在构造函数中设置的内容时,这个技巧才真正有用。否则,您最终需要从shared_ptr
向下投射Base*
指针,在这种情况下,您应该首先使用shared_ptr<DerivedA>
。
我可以看到像在IUnknown::Release
的实现中使用代码,但从来没有在析构函数中使用过。 Base
析构函数仅在派生对象被销毁后运行,尝试在此时delete
派生对象是未定义的行为。 我很确定在这种特殊情况下你会得到无限递归。
- 什么时候调用组成单元对象的析构函数
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 内联映射初始化的动态atexit析构函数崩溃
- 什么时候调用析构函数
- 优先顺序:智能指针和类析构函数
- C++-明确何时以及如何调用析构函数
- 使用基类指针创建对象时,缺少派生类析构函数
- 在c++中使用向量时,如何调用构造函数和析构函数
- 重载运算符new[]的行为取决于析构函数
- 我需要知道编译器如何在cpp中使用析构函数
- 为什么在使用转换构造函数赋值后调用C++类的析构函数?
- 析构函数调用
- 通过引用传递-为什么要调用这个析构函数
- 对具有动态分配的内存和析构函数的类对象的引用
- 重载 -> shared_ptr 个实例中的箭头运算符<interface>,接口中没有纯虚拟析构函数
- C++成员的析构函数顺序与shared_ptr
- 如何在 CRTP 中实现析构函数?
- CRTP 在父级析构函数中调用子函数
- C++:CRTP 析构函数
- 处理CRTP设计的受保护/私有构造函数/析构函数