C++:CRTP析构函数?

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,我做公共继承.它完全没问题,还是有问题?

非常感谢你.

Ste*_*sop 8

你的析构函数肯定是错误的.类的析构函数不会也不能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>来开始.

  • 关于`shared_ptr`的有趣事实+1. (3认同)