16

是否可以有一个虚拟删除操作员?我不是在说析构函数,我指的是实际的运算符重载。

减去(在大多数情况下)重载 new 和 delete 是一个很大的坏主意这一事实(是的,我已经知道这是异端邪说),我想知道使用虚拟删除运算符会产生什么样的影响。

我正在考虑尝试使用虚拟删除,因为有时我可能有一个重载删除的子类,存储在基类指针中。从技术上讲,我真的没有看到这个案例取得太多成果,除非我有不同节点类型的树(如果你问我,这首先是一个潜在的危险想法)。

我只想知道虚拟或非虚拟删除运算符覆盖的潜在优缺点是什么。

4

4 回答 4

17

您不能明确声明operator deletevirtual.

它是一个静态成员函数,即使您不提供关键字static

但是在使用最派生类中定义的那个的意义上operator delete 已经是虚拟的。您可能会选择将其视为由析构函数调用。甚至可能是。;-)


C++11 §12.4/12
“在定义虚拟析构函数(包括隐式定义(12.8))时,在析构函数的类(10.2)的范围内查找非数组释放函数,并且,如果未找到声明,则在全局范围内查找该函数。”


C++11 §12.5/4
“如果删除表达式以一元运算符开头::,则在全局范围内查找释放函数的名称。否则,如果delete-expression用于释放静态类型具有虚拟析构函数的类对象,则释放函数是在定义动态类型的虚拟析构函数 (12.4) 时选择的函数。117否则,如果delete-expression用于释放类T或其数组的对象,则对象的静态和动态类型应相同,并在释放函数的范围内查找释放函数的名称T. 如果此查找未能找到该名称,则在全局范围内查找该名称。如果查找的结果不明确或无法访问,或者如果查找选择了布局释放函数,则程序是非良构的。”

于 2012-12-16T00:17:32.580 回答
7

不——即使你没有这样标记它,当/如果你为一个类重载new/时delete,它们最终会成为静态成员函数1,并且静态成员函数不能是虚拟的。

为了工作,它们确实需要是静态的——它们用于为对象分配/释放内存,因此必须在对象开始构造之前/完成销毁之后发生。您显然不能让它为最终将成为类的实例的内存分配内存,同时让它依赖于已经该类的实例(虚函数所做的)。


  1. §12.5/1:

类 T 的任何分配函数都是静态成员(即使没有显式声明为静态的)。

和§12.5/6:

类 X 的任何释放函数都是静态成员(即使未显式声明为静态成员)。

...对于任何关心官方声明的人。有趣的是,当您分配时它是“T 级”,而当您释放时它是“X 级”。

于 2012-12-16T00:17:21.103 回答
4

不 - 你不能有一个虚拟运算符 delete -特定于类newdelete重载必须是静态成员函数 - 特定于类,而不是对象。

您不能拥有虚拟静态成员函数。

请参阅标准的第 12.5.7 节,其中指出“由于成员分配和释放函数是静态的,它们不能是虚拟的。”

于 2012-12-16T00:21:25.943 回答
-2

1)是的,当然你可以重载删除。不,重载不能是虚函数。

2)“优点和缺点”完全取决于你想要做什么。

3) 当然,操作符重载的整个想法——就像在 C++ 中一样——可以说是愚蠢、不必要和危险的。

呜呜呜……

4)如果你不需要它,那就不要这样做:)

恕我直言...

于 2012-12-16T00:17:09.417 回答