繁体   English   中英

C ++:CRTP析构函数?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM