C++ 为什么必须使用纯虚拟析构函数';什么是空的?它应该是内联的吗?

C++ 为什么必须使用纯虚拟析构函数';什么是空的?它应该是内联的吗?,c++,C++,我在其他线程中读到,当您实现纯虚拟析构函数(是的,它可以有一个实现)时,它必须为空,并且应该(?)是内联的。它应该是空的吗?若然,原因为何?它应该是内联的吗?若然,原因为何 编辑: 这就是纯虚拟描述器实现的方式: class A{ virtual ~A() = 0; } inline A::~A(){ //implementation } 听起来很奇怪 首先,“是的,它可以实现”是一句相当奇怪的话。它实际上需要有一个实现(至少在C++98中)。这是没有办法的。任何使用过纯虚拟

我在其他线程中读到,当您实现纯虚拟析构函数(是的,它可以有一个实现)时,它必须为空,并且应该(?)是内联的。它应该是空的吗?若然,原因为何?它应该是内联的吗?若然,原因为何

编辑: 这就是纯虚拟描述器实现的方式:

class A{
    virtual ~A() = 0;
}

inline A::~A(){
    //implementation
}
听起来很奇怪

首先,“是的,它可以实现”是一句相当奇怪的话。它实际上需要有一个实现(至少在C++98中)。这是没有办法的。任何使用过纯虚拟析构函数的人都知道这一点

其次,它不应该总是空的。它只是应该做它需要做的事情。如果没有明确的操作,请将其留空。否则,它不会是空的

最后,它可以是内联的,也可以是非内联的——这没有什么区别。事实上,它不能在类定义中定义。定义必须在类1之外(内联或非内联-无所谓)。

纯虚拟析构函数必须有一个实现(假设您至少有一个具体的派生类)

没有规则规定纯虚拟析构函数必须有空的主体。我也不知道有什么原因应该这样做,除了大多数析构函数都应该有一个空体的原因

纯虚拟析构函数可以是内联的,也可以是非内联的。我希望每种方法的好处都取决于基类和具有非平凡析构函数的非静态成员的数量


不过,还有一个问题:在某些流行的编译器上,如果析构函数是为类定义的唯一虚拟方法,那么最好将其设置为非内联,以帮助实现处理其多态性魔法。

请记住,“必须”和“应该”的含义不同

纯虚拟析构函数可以是非空的。不知道谁会说别的

应该是吗?是的,因为抽象基不应该删除任何内容。你会发现,你会不时违反后者的“应该”,因此,当然,也可能违反前者


它应该是内联的吗?它既不应该也不应该。我想不出通过“内联”可以获得什么,因为实现可以自由地忽略内联线和内联非内联线。一般来说,虽然没有理由只为抽象类中的空析构函数创建实现文件。

您需要实现纯虚拟析构函数,因为, 虚拟析构函数的工作方式是,首先调用最派生类的析构函数,然后调用每个基类的析构函数。这意味着编译器将生成对基类纯虚拟析构函数的调用,即使该类是抽象的,因此您必须为该函数提供一个主体。 如果您不提供正文,链接器将抱怨缺少符号

可能有这样一种情况,您希望基类是抽象的,即使您的类不包含任何纯虚函数。在这里声明纯虚拟析构函数将使类抽象。在这种情况下,析构函数可以有空的主体。
为了避免为调用空体析构函数支付开销,请将其声明为内联。

纯虚拟的东西如何实现?您能否提供指向提及此问题的其他线程的链接?这将帮助我们破译它的意思。如果该类被继承,它应该有一个虚拟析构函数,但纯虚拟析构函数没有多大意义。似乎这个问题有一些有趣的信息:@bits:不正确。任何纯虚函数都可以有一个定义。在大多数情况下,只有在异常情况下才会调用它。但是析构函数必须有一个定义,即使它是纯虚拟的。我说“是的,它可以有一个实现”,因为不是每个人都知道纯虚拟函数可以有一个实现,我预计人们会开始问我这个问题,所以我提出了免责声明。没有帮助。你在说哪些“流行的编译器”?我觉得这种说法难以相信。请给出一个具体的例子。@Alf:在g++中,这有点不同,但没什么大不了的。尽管如此,我相信g++标准库的作者出于这个原因选择了使一些析构函数非内联?有没有关于这个问题的错误报告?问题是(许多编译器)在翻译单元级别,编译器不知道是否需要析构函数,所以它必须在每个对象文件中创建副本。然后链接器可以删除所有这些副本。这在任何完全独立的编译模型中都是不可避免的。您需要一些链接时编译来解决它。没有g++错误。只是,如果一个多态类没有非内联虚拟成员,那么包含类定义的TUs对象文件会稍微大一点,链接会花费更长的时间。