类中的纯虚析构函数定义会产生编译错误

nit*_*ian 13 c++ inheritance destructor pure-virtual

pure virtual destructor基类应该有一个定义.否则编译器将在链接时生成从派生类析构函数调用基类析构函数,并将导致链接错误.

我试图在基类中定义纯虚拟析构函数,如下所示:

class base
{
   public:
      base()
      {
         cout << "constructor in base class\n";
      }

      virtual ~base()=0
      {}
};
Run Code Online (Sandbox Code Playgroud)

这给出了编译错误:

错误:函数定义的纯指定符

然后我尝试在基类之外定义函数,如下所示:

class base
{
   public:
      base()
      {
         cout << "constructor in base class\n";
      }

      virtual ~base()=0;
};

base::~base()
{

}
Run Code Online (Sandbox Code Playgroud)

这将删除编译错误,它的行为与我的理解相同.

但我的问题是如何在基类之外定义纯虚拟析构函数来消除编译错误?

ron*_*nag 11

你的第二个例子是正确的.

许多其他答案都假设使用默认实现的纯虚函数是非法的,但这是不正确的.

对于纯虚拟析构函数,您必须有一个定义(请参阅xmoex答案中的链接).

确实如此:

§10.4/ 2函数声明不能​​同时提供纯指定符和定义

但是,正如您所注意到的那样,可以在声明之外提供定义.


xmo*_*oex 7

我看了这个页面:

http://www.gotw.ca/gotw/031.htm

从我的理解,纯虚拟析构函数必须有一个定义(甚至是一个空的),因为每个派生类都必须调用基类析构函数


Ada*_*man 5

写入的语法无效:

virtual ~base()=0
{}
Run Code Online (Sandbox Code Playgroud)

如果要提供纯虚拟成员函数的实现,则应该在类之外执行.大多数情况下你不应该这样做,因为永远不应该调用纯虚函数.但是,可以定义纯虚函数的实现.

实际上,纯虚拟析构函数必须具有实现.这是因为无论给定类中的析构函数是否为纯虚拟对象,都会在对象销毁时调用所有基类的析构函数.

因此,如果您创建base从那时派生的任何类的实例,那么将调用该对象所属的所有类的析构函数,包括base::~base()析构函数.如果您没有定义它,链接器将找不到所需的符号并会抱怨.