[英]C++ : CRTP destructor?
在一个项目上,我有以下问题:
我有一个非常简单的继承方案(我需要继承而不是组成):
班级基础
->类DerivedA
->类DerivedB
->类DerivedC
A,B和C源自Base,仅此而已。 所以现在我有2个选择:
具有虚拟性的公共继承
没有虚拟的私人继承
由于某些优化原因(我需要大量内联),我不需要虚拟性...,也不需要私有继承。 我认为剩下的唯一选择就是CRTP。 但是基类有300种功能,而在其中实现CRTP实在是一件痛苦的事。
所以我想知道以下解决方案是否有效:我仅在基类的析构函数中使用CRTP:
template<class TCRTP> class Base
{
~Base() {delete static_cast<TCRTP*>(this);}
}
TCRTP将是DerivedA,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
派生对象是未定义的行为。 我敢肯定,在这种情况下,您将获得无限递归。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.