假设我有以下接口类,以便"写入接口,而不是实现":
class IDrawable
{
public:
virtual void
Draw() const = 0;
protected:
~IDrawable() = default;
};
客户端不应该能够通过接口指针删除动态分配的可抽取项,因此IDrawable
的析构函数是受保护的和非虚拟的,根据C++核心准则C.35:基类析构函数应该是公共的和虚拟的,或者受保护的是非虚拟的。
现在对于实现这个接口的类:
class CDrawable : public IDrawable
{
public:
void
Draw() const override;
};
当然,这会发出警告:
CDrawable
具有虚拟函数但非虚拟析构函数。
为了解决这个问题,我们现在必须向CDrawable
添加一个虚拟析构函数。但是,在派生类中有一个虚拟析构函数感觉就像是一种代码气味,我以前从未见过(?(在IDrawable
中有虚拟受保护的析构函数不是更有意义吗?
技术上没有问题。CDrawable
有一个公共的非虚拟析构函数(隐式定义(。调用它不会导致未定义的行为,当然,除非它是在从CDrawable
派生的类上调用的。如果您只引用了IDrawable
并调用了它的析构函数,那么您将跳过对派生类的销毁(我认为这会导致UB(,但由于它不可公开访问,所以这不是问题。
是的,你收到了警告。然而,这只是一个警告,表明可能有什么问题。在这种情况下,事实并非如此。