【问题标题】:C++ Virtual operator delete?C ++虚拟运算符删除?
【发布时间】:2012-12-03 13:25:17
【问题描述】:

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

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

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

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

【问题讨论】:

  • 您可以在大约 30 秒内使用编译器自己回答第一个问题。
  • @EJP 是的。我有一个可以测试它的设置。一秒。
  • 是的...谢谢大家的澄清。愚蠢的问题是愚蠢的! =)
  • +1 好问题。他他

标签: c++ inheritance operator-overloading virtual delete-operator


【解决方案1】:

您不能将operator delete 显式声明为virtual

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

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


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 的范围内查找函数的名称。如果此查找未能找到名称,则在 全局范围。如果查找结果不明确或无法访问,或者查找选择了一个展示位置 释放函数,程序格式错误。”

【讨论】:

  • 那么,简单来说,如果一个对象有一个虚拟的~destructor(),它会使用关联的删除重载吗?那是..很高兴知道... =)
  • @Serge:避免使用最派生类的释放函数的唯一方法是有一些未定义的行为(例如,通过基类指针删除并且没有虚拟析构函数)。
  • 这为我提供了一种方法来保证调用正确的删除重载。我所要做的就是提供一个虚拟的虚拟析构函数。
【解决方案2】:

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

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


  1. §12.5/1:

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

和§12.5/6:

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

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

【讨论】:

    【解决方案3】:

    不 - 您不能使用虚拟运算符 delete - 特定于类的 newdelete 重载必须是静态成员函数 - 特定于类,而不是对象。

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

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

    【讨论】:

    • 谢谢,我没有意识到它们是静态的。主要是因为我不必将它们声明为静态的。
    【解决方案4】:

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

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

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

    太棒了.....

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

    恕我直言...

    【讨论】:

    • -1 嗯,我认为将operator delete 声明为virtual 是无效的。让我检查一下。对,因此 Visual C++ 惊呼:“错误 C2650:'delete':不能是虚函数”
    • +1 干杯。 - Alf:可以超载:是的。可以作为虚函数重载:不。你是对的。我编辑了我的回复。谢谢你:)
    猜你喜欢
    • 2021-11-12
    • 2010-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-19
    • 1970-01-01
    相关资源
    最近更新 更多