提问者:小点点

对于接口类,C核心准则C35“基类析构函数应该是公共和虚拟的,或者是受保护的和非虚拟的”是错误的吗?


假设我有以下接口类以“写入接口,而不是实现”:

class IDrawable
{
public:

    virtual void
    Draw() const = 0;

protected:

    ~IDrawable() = default;
};

客户端不应该能够通过接口指针删除动态分配的可绘制对象,因此IDrawable的析构函数是受保护的和非虚拟的,根据C Core指南C.35:基类析构函数应该是公共的和虚拟的,或者是受保护的和非虚拟的。

现在对于实现此接口的类:

class CDrawable : public IDrawable
{
public:

    void
    Draw() const override;
};

这当然会发出警告:

CDrawable具有虚函数但非虚析构函数。

为了解决这个问题,我们现在必须在CDrawable中添加一个虚拟析构函数。但是在派生类中有一个虚拟析构函数感觉就像是一种代码气味,我以前没有见过(?)在IDrawable中有一个虚拟受保护的析构函数不是更有意义吗?


共1个答案

匿名用户

技术上没有问题。您的CDrawable有一个公共的非虚拟析构函数(隐式定义)。调用它不会导致未定义的行为,当然,除非它是在从CDrawable派生的类上调用的。如果您只有对IDrawable的引用并调用了它的析构函数,您将跳过对派生类的销毁(我认为会导致UB),但由于它不能公开访问,这不是问题。

是的,你会得到一个警告。然而,这个警告只是一个迹象,表明可能有什么问题。在这种情况下,它不是。