C++类接口类的析构函数

sdg*_*sdg 24 c++

开始在现有代码库上使用PC-Lint(恐惧和恐惧).

它抱怨的一件事是:

 class IBatch
 {
 public:
    virtual void StartBatch() =0;
    virtual int CommitBatch() =0;
 };
Run Code Online (Sandbox Code Playgroud)

当另一个类派生出来时,它就像一个接口一样使用它

base class 'IBatch' has no destructor
Run Code Online (Sandbox Code Playgroud)

所以,问题是:当您创建如上所述的接口类时,您是否始终包含虚拟析构函数?为什么?(是样式还是编码错误?)

编辑:应该说我不希望或希望IBatch 的用户破坏,他们只是一个服务的消费者,通过这个接口到一些外部实现类(如果这会有所作为)

Jam*_*lis 30

基类析构函数应该是公共的和虚拟的,或者是受保护的和非虚拟的.

(Herb Sutter,本周大师#18:"虚拟")


ste*_*anB 8

编码错误 - 如果通过指向基类的指针调用,派生类的析构函数将永远不会被调用.

当你实现IBatch并通过指向基类(指向IBatch)的指针来引用你的派生类,并且你调用delete指向基类的指针时,你最终可能会遇到内存泄漏,因为派生类的析构函数永远不会被调用.

基本规则是当一个类至少有一个virtual需要具有virtual析构函数的方法时.

class IBatch
{
    public:
       virtual void f() = 0;
};

class A : public IBatch
{
    public:
       void f() {}
       ~A() {}
};

IBatch * a = new A();
a->f();    // calls A::f()
delete a;  // calls IBatch::~IBatch() not A::~A()
Run Code Online (Sandbox Code Playgroud)

  • 如果我不希望IBatch接口的用户在我身上调用delete,那该怎么办?来自@James的受保护和非虚拟答案是什么? (2认同)
  • @sdg:是的。受保护的析构函数可防止*其他* 类(在该类层次结构之外)对其调用 delete。 (2认同)

Bil*_*eal 7

如果有虚函数,则需要有一个虚析构函数.总是.它只是一个接口类并不重要 - 它仍然需要虚拟析构函数.

要么是,要么需要protected非虚拟析构函数.但是,您无法使用接口指针删除该对象.

  • 除非析构函数受到保护(即,您正在阻止通过指向接口的指针进行删除). (2认同)

Ale*_*lli 5

一个带有虚函数但没有虚析构函数的类是可疑的,而且很可能是错误的:在这里看到一个好的和更精确的解释。