【问题标题】:Static member placement delete signature?静态成员放置删除签名?
【发布时间】:2017-05-09 09:57:58
【问题描述】:

我有一个项目可以严格控制分配内存的内容和方式。我有一个基类,用于可能在堆上分配的东西,operator newoperator delete 及其数组变体的静态重载。这些都可以完美运行,完全没有任何警告。

对于所有只允许放置新的东西都有一个终极基类:

class Object
{
public:
    static void* operator new(size_t, void*);
    static void* operator new[](size_t, void*);
    static void operator delete(void*, void*);
    static void operator delete[](void*, void*);
};

实现很简单,在相应的 .cpp 文件中。 operator news 返回指针,operator deletes 什么也不做。

当我在 VS2015 下编译时,使用 new (ptr) DerivedFromObject() 会产生以下警告。异常处理设置为/EHa

warning C4291: 'void *Object::operator new(std::size_t,void *)': no matching operator delete found; memory will not be freed if initialization throws an exception

我试过弄乱签名:添加noexcept,将size_t 添加到operator delete,但似乎没有任何效果。静态成员放置operator delete的正确形式是什么?

【问题讨论】:

标签: c++


【解决方案1】:

看来我需要在每个派生类中声明operator deletes 才能消除警告。

【讨论】:

  • No you don't。请务必公开继承。
  • 我确实公开继承了。不过,这不会是我在这个项目中遇到的第一个编译器错误,例如在调试版本中执行 ptr->~DerivedFromObject() 会在无法访问的代码中生成对非放置 operator delete 的引用,该代码在发布中进行了优化。
  • ptr->~DerivedFromObject() 根本没有生成对 operator delete 的引用。这只是一个直接的析构函数调用。我并不是说听起来令人沮丧,但您的项目可能只是遭受了编译器拼命警告您的未定义行为的实例。
  • 确实是这样,因为当我注释掉该行时,我得到了一个链接器错误,该错误消失了 :) 我还查看了 dumpbin /disasm 并且我的析构函数调用实际上调用了一些调用真正的析构函数,做了一些复杂的检查,然后在不可能发生的情况下调用全局运算符 delete。 /O2 意识到了这一点,消除了那部分,并内联了 thunk,有效地使其成为直接的析构函数调用。
  • 我不会在任何地方调用它。作为标准,如果/当我的构造函数抛出异常时,它会被调用。为什么ptr->~ClassName() 调用非放置operator delete 虽然我无法理解,但由于它只是调试,我投票支持编译器错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-29
  • 1970-01-01
相关资源
最近更新 更多