繁体   English   中英

您如何在CRTP中实现析构函数?

[英]How do you implement the destructor in CRTP?

实现奇怪的重复模板模式(CRTP)时,是否需要析构函数是虚拟的? 如果不是,那么正确的非虚拟实现是什么?

我将提供一个示例,希望可以使事情变得更轻松:

template<typename T>
class Base
{
public:
    virtual ~Base()
    {
        // Should this be virtual? Non-virtual?
        std::cout << "Base::~Base()\n";
    }
};

class Derived : public Base<Derived>
{
public:
    ~Derived() override
    {
        std::cout << "Derived::~Derived()\n";
    }
};

int main()
{
    Base<Derived>* b = new Derived;
    delete b;
}

结果:

Derived::~Derived()
Base::~Base()

这里有现场样本

编辑:更新了示例以使用运行时多态性,以便需要虚拟析构函数进行适当的清理。

从这个意义上说,CRTP基类与任何其他基类没有什么不同。 仅当要通过指向Base<Derived>的指针delete Derived类型的对象时,才需要虚拟析构函数。 否则,不需要虚拟析构函数。

Base<Derived>* b = new Derived;
delete b; // Base<Derived>::~Base<Derived> must be virtual

在您显示的示例中,不需要虚拟析构函数。 仅当您可能需要使用指向基类的指针来调用虚拟析构函数时,才需要虚拟析构函数,在这种情况下,与重写函数一样,它必须是虚拟的。 而且,对于您所显示的CRTP类,几乎不需要删除Base<T>而不是T本身。

int main()
{
    Derived *a = new Derived();
    // we have the right type anyway, so dont actually need a virtual anything (even normal virtual methods)
    delete a;

    Derived *a = new Dervied();
    Base<Derived> *b = a;
    // We are now deleting via a parent class, so this needs a virtual destructor.
    // This is pretty uncommon with a simple CRTP however.
    delete b;
}

如果要在指向派生对象的基类的指针上调用delete ,则需要一个虚拟析构函数,这就是它的全部。 CRTP或没有CRTP。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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