是否可以有虚拟删除操作员? 我说的不是析构函数,我指的是实际的运算符重载。
除去(在大多数情况下)重载 new 和 delete 是一个大坏主意的事实(是的,我已经知道这是异端邪说),我想知道使用虚拟删除运算符会产生什么样的影响。
我正在考虑尝试使用虚拟删除,因为有时我可能有一个重载删除的子类,存储在基类指针中。 从技术上讲,我真的没有看到这种情况取得太多成果,除非我有一棵不同节点类型的树(如果你问我,这首先可能是危险的想法)。
我只是想知道虚拟或非虚拟删除运算符覆盖的潜在优点和缺点是什么。
您不能将
operator delete
显式声明为 virtual
。
它是一个静态成员函数,即使您不提供关键字
static
。
但是
operator delete
已经是 virtual 了,因为使用了最派生类中定义的虚拟的。您可能会选择将其视为由析构函数调用。甚至可能是。 ;-)
C++11 §12.4/12:
“在虚拟析构函数的定义点(包括隐式定义 (12.8)),非数组 在析构函数的类(10.2)的范围内查找释放函数,并且,如果没有声明 找到后,会在全局范围内查找该函数。”
C++11 §12.5/4:
“如果 delete-expression 以一元运算符开头,则在以下位置查找释放函数的名称: 全球范围。否则,如果使用 delete-expression 来释放静态类型具有的类对象 虚拟析构函数,释放函数是在动态定义时选择的函数 类型的虚拟析构函数 (12.4)。117 否则,如果使用 delete-expression 来释放 的对象 类::
或其数组,对象的静态和动态类型应相同,并且释放 函数的名称在T
的范围内查找。如果此查找未能找到该名称,则会在以下位置查找该名称 全球范围。如果查找结果不明确或无法访问,或者查找选择了展示位置 释放函数,程序格式错误。”T
不——即使你不这样标记它,当/如果你为一个类重载
new
/delete
时,它们最终会成为静态成员函数1,并且静态成员函数不能虚拟。
为了工作,它们确实需要是静态的——它们用于为对象分配/释放内存,因此必须在对象开始构造之前/完成销毁之后发生。显然,您不能让它为最终成为类实例的对象分配内存,同时让它依赖于已经成为类的实例(虚函数就是这样做的)。
类 T 的任何分配函数都是静态成员(即使没有显式声明为静态)。
和§12.5/6:
类 X 的任何释放函数都是静态成员(即使没有显式声明为静态)。
...对于任何关心官方声明的人。有趣的是,当你分配时它是“T 类”,而当你释放时它是“X 类”。
不 - 你不能使用虚拟运算符删除 - 特定于类的
new
和 delete
重载必须是静态成员函数 - 特定于类,而不是特定于对象。
你不能有虚拟静态成员函数。
请参阅标准第 12.5.7 节,其中指出“由于成员分配和释放函数是静态的,因此它们不能是虚拟的。”