C ++的“接口”应该有一个虚拟析构函数
可能重复:
类似于C ++界面的类的析构函数
考虑一个C ++抽象类的简单例子,用于模拟一个接口:
class IAnimal { virtual void walk()=0; virtual ~IAnimal(){} };
有没有更好的parsing器,或不? 我不认为析构函数可以是纯粹的虚拟,至less我的testing给链接器错误,所以应该包括一个空的析构函数?
编辑:对不起,错字。 它是一个析构函数而不是构造函数。
你应该总是使用带有接口的虚拟析构函数。 例如:
IAnimal* animal = new Lion(); delete animal;
现在使用什么析构函数? 肯定不是狮子的析构函数,因为接口不知道狮子的析构函数 。
所以,如果你的界面没有内存pipe理,就有这个问题:
virtual ~IAnimal(){}
看看Herb Sutter的这篇文章
特别
仅针对析构函数的特例:
准则4:基类析构函数应该是public和virtual,或者是protected和nonvirtual。
这假设基类是一个“接口”类,因为它大部分应该是。
这取决于您是否打算使用指向接口类的指针来多态地pipe理对象的生命周期。
如果这样做,那么析构函数必须是虚拟的,才能正确删除对象。 删除没有虚拟析构函数的基类指针是无效的,并给出未定义的行为。
如果你不这样做,那么你应该通过使析构函数非虚拟和保护来强制执行,所以只有派生类可以被删除。
我认为它应该是一个纯粹的虚拟析构函数接口,所有其他的方法也是纯虚拟的。
不使析构函数虚拟化的唯一原因是为了节省vptr
所需的空间。 因为你还需要vptr
,因为你有另一个虚函数,我会使析构函数变成虚拟的。
应该包含一个空的构造函数,因为一个接口的典型用法是将一个指针指向一个容器中的某个具体对象,否则这个指针会调用错误的析构函数而不能正确地清理内存。 所以如果有人要通过指向Ianimal的指针来删除派生对象,那么创build一个虚拟的析构函数,否则使你的析构函数成为非虚拟的并且被保护。 使你的析构函数纯粹是虚拟的可能不是一个好主意,因为它迫使派生类的实现者重载你的析构函数,尽pipe他们可能不想做任何事情