假设我有以下接口类以“写入接口,而不是实现”:
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
中有一个虚拟受保护的析构函数不是更有意义吗?
技术上没有问题。您的CDrawable
有一个公共的非虚拟析构函数(隐式定义)。调用它不会导致未定义的行为,当然,除非它是在从CDrawable
派生的类上调用的。如果您只有对IDrawable
的引用并调用了它的析构函数,您将跳过对派生类的销毁(我认为会导致UB),但由于它不能公开访问,这不是问题。
是的,你会得到一个警告。然而,这个警告只是一个迹象,表明可能有什么问题。在这种情况下,它不是。