我在其他线程中读到,当你实现一个纯虚析构函数时(是的,它可以有一个实现)它必须是空的,并且应该(?)是内联的。它应该是空的吗?如果是这样,为什么?它应该是内联的吗?如果是这样,为什么?
编辑: 这就是纯虚拟析构函数可以实现的方式:
class A{
virtual ~A() = 0;
}
inline A::~A(){
//implementation
}
答案 0 :(得分:24)
纯虚析构函数必须具有实现(假设您至少有一个具体的派生类)。
没有规则纯虚拟析构函数必须具有空体。我也不知道它应该是什么原因,除了大多数析构函数应该空体的原因相同。
纯虚拟析构函数可以是内联或非内联。我希望每个的好处取决于基类的数量和非平凡析构函数的非静态成员。
另一个问题是:在某些流行的编译器中,如果析构函数是为该类定义的唯一虚拟方法,那么将其设置为非内联是一个好主意,以帮助实现处理其多态性魔法。 / p>
答案 1 :(得分:8)
听起来很奇怪。
首先,“是的,它可以有一个实现”是一个相当奇怪的评论。实际上 required 有一个实现(至少在C ++ 98中)。没有办法绕过它。任何使用纯虚析构函数的人都知道它。
其次,它不应该总是空的。它应该只是做它需要做的事情。如果您没有明确的任何事情,请将其留空。否则,它不会是空的。
最后,它可以是内联的或非内联的 - 它没有任何区别。真实的是它无法在类定义中定义。定义必须是非同类的(内联或不内容 - 无关紧要)。
答案 2 :(得分:5)
您需要实现纯虚拟析构函数,因为, 虚析构函数的工作方式是首先调用派生类最多的析构函数,然后调用每个基类的析构函数。这意味着编译器将生成对基类纯虚析构函数的调用,即使该类是抽象的,因此您必须为该函数提供一个主体。 如果您不提供正文,链接器会抱怨缺少符号。
可能有这种情况,即使您的类不包含任何纯虚函数,您希望您的基类是抽象的。在这里声明纯虚拟析构函数将使您的类抽象化。在这种情况下,你的析构函数可以有空体。 为了避免支付对空体析构函数的调用的开销,请将其声明为内联。
答案 3 :(得分:3)
记住“必须”和“应该”意味着不同的事情......
纯虚析构函数可以是非空的。不知道谁可能会这么说。
应该吗?是的,因为抽象基础不应该删除任何内容。你会发现你不时会违反后者“应该”,因此,当然也可以是前者。
它应该是内联的吗?它既不应该也不应该。由于实现既可以自由地忽略内联,也可以内联非内联,因此我无法想到你通过“内联”明显获得的任何东西。一般来说,没有理由创建一个实现文件,只不过是抽象类中的空析构函数。