C++纯虚拟类是否需要定义?

Mar*_* Lu 15 c++ class

考虑:

// in header.h
class A {
public:
    virtual ~A() = 0;
};


class B : public A {
public:
    ~B() override {}
}
Run Code Online (Sandbox Code Playgroud)

链接器报告无法解析:

外部符号"public:virtual __thiscall A ::〜(void)"在函数"public:virtual __thiscall B :: ~B(void)"中引用

我发现我必须写出定义A::~A().

我曾经认为纯虚拟类定义了接口(函数声明),并且它们不必包含函数定义.我应该为纯虚基类中的所有虚函数编写定义吗?或者我应该只需要编写析构函数?

Fat*_*KIR 17

这是因为与常规虚函数不同,析构函数不仅仅被覆盖.当您在基类上调用常规虚函数时,最终调用已覆盖该函数的函数.

但是,在析构函数的情况下,还必须调用基类的析构函数.但由于您未提供实现~A(),因此您的代码无法链接.

但是你可以定义函数,即使它是纯虚拟的:就像这里一样.

  • 实际上,析构函数可以是纯虚拟的并且也有一个定义:`virtual~A()= 0 {}` (4认同)
  • 纯虚函数通常可以有定义. (2认同)

Dav*_*aim 10

C++ 纯虚拟类是否需要定义?

第一个错误是你代表自己发明了条款.没有"纯粹的虚拟课"这样的东西.只有"虚拟功能"和"纯虚功能".理解没有这样的东西"纯虚拟类"是理解为什么这个问题不成立的关键.

我以前认为纯虚拟类定义了一个接口(函数声明)

我认为C++不是你的第一语言,而是继Java/C#之后的第二语言,你认为Java/C#的思想与C++无关.

C++有接口 - 它只是类的声明:

struct A{

    void doNothing();

};

//A.cpp:
void A::doNothing(){

}
Run Code Online (Sandbox Code Playgroud)

这是struct A的接口.它与继承,虚函数还是多态有关吗?不,它只是类的声明,其中存在哪些方法和属性.

每个类都需要一个有效的析构函数来允许程序清理对象资源 - 内存等.它与多态无关.在你的例子中,A需要以某种方式被破坏.B继承它并不重要.当它超出范围时,它必须告诉程序如何处理它.

正如评论中所提到的,如果你只想要一个虚拟析构函数(所以不会出现UB A* a = new B()),只需将析构函数声明为默认值:

virtual ~A() = default;
Run Code Online (Sandbox Code Playgroud)

  • C++中Java的*interface*等价物是一个只有纯虚函数的类.而你的*struct A {...};*上面是结构的定义.声明只是*struct A;* (2认同)