Vin*_*ent 0 c++ inheritance crtp
在一个项目中,我有以下问题:
我有一个非常简单的继承方案(我需要继承而不是组合):
班级基地
- >类DerivedA
- >类DerivedB
- >类DerivedC
A,B和C来自Base,这就是全部.所以现在我有两个选择:
公共继承与虚拟
没有虚拟的私有继承
出于某些优化原因(我需要很多内联)我不想要虚拟化......我不想要私有继承.我认为唯一的选择是CRTP.但是基类有300个功能,在其中实现CRTP将是一个真正的痛苦.
所以我想知道以下解决方案是否有效:我只在基类的析构函数中使用CRTP:
template<class TCRTP> class Base
{
~Base() {delete static_cast<TCRTP*>(this);}
}
Run Code Online (Sandbox Code Playgroud)
其中TCRTP将是DerivedA,B或C,我做公共继承.它完全没问题,还是有问题?
非常感谢你.
你的析构函数肯定是错误的.类的析构函数不会也不能delete
是对象的内存.
如果没有虚函数,你对公共继承的反对意见是什么?(至少)有两种方法可以防止某人通过基指针意外删除派生对象.一个是制作基础析构函数protected
.
另一种方法是将派生类的动态分配实例直接填充到a中shared_ptr
.这甚至可以是shared_ptr<Base>
:
std::shared_ptr<Base> foo(new DerivedA(...));
Run Code Online (Sandbox Code Playgroud)
因为shared_ptr
有一个模板构造函数来捕获其参数的类型,所以Base*
指针将被转换为DerivedA*
与之关联的删除函数shared_ptr
,因此被正确删除.没有人应该如此愚蠢,试图从a中提取指针shared_ptr
并将其删除为Base*
.
当然,如果你没有虚函数,那么只有当派生类之间的唯一区别是它们在构造函数中设置的时候,这个技巧才真正有用.否则你最终需要向下转发Base*
指针shared_ptr
,在这种情况下你应该使用a shared_ptr<DerivedA>
来开始.