Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cassandra/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++11 为什么虚拟析构函数需要运算符delete?_C++11_Operator Keyword_Virtual Destructor - Fatal编程技术网

C++11 为什么虚拟析构函数需要运算符delete?

C++11 为什么虚拟析构函数需要运算符delete?,c++11,operator-keyword,virtual-destructor,C++11,Operator Keyword,Virtual Destructor,考虑以下代码: class Base { public: #ifdef __VIRTUAL__ virtual ~Base() {} #else ~Base() {} #endif }; class Derived : public Base { public: ~Derived() {} private: static void operator delete(void*) = delete; }; int main() { Derived d; }

考虑以下代码:

class Base {
public:
#ifdef __VIRTUAL__
   virtual ~Base() {}
#else
   ~Base() {}
#endif
};

class Derived : public Base {
public:
    ~Derived() {}
private:
    static void operator delete(void*) = delete;
};

int main() {
    Derived d;
}
它将使用cmd成功编译

g++ -std=c++11 main.cpp
g++ -std=c++11 -D__VIRTUAL__ main.cpp
但是使用cmd失败了

g++ -std=c++11 main.cpp
g++ -std=c++11 -D__VIRTUAL__ main.cpp
输出显示需要
操作员删除

main.cpp: In destructor ‘virtual Derived::~Derived()’:
main.cpp:12:17: error: use of deleted function ‘static void Derived::operator delete(void*)’
     ~Derived() {}
                 ^
main.cpp:14:17: error: declared here
     static void operator delete(void*) = delete;
                 ^
main.cpp: In destructor ‘virtual Derived::~Derived()’:
main.cpp:12:17: error: use of deleted function ‘static void Derived::operator delete(void*)’
     ~Derived() {}
                 ^
main.cpp:14:17: error: declared here
     static void operator delete(void*) = delete;
                 ^
这意味着如果我使用虚拟析构函数,我不能删除
操作符delete


为什么会发生这种情况,为什么虚拟析构函数需要全局
运算符删除
,即使是在堆栈上创建的。

只有在删除具有动态存储持续时间的对象时才会调用
运算符删除
函数。你的程序没有调用它

但是,该标准要求,如果存在虚拟析构函数,则此函数可用,即使对象从未实际动态使用

在C++17标准中,这是[class.dtor]/13:

在虚拟析构函数的定义点(包括隐式定义),非数组解除分配函数被确定为表达式
delete this
,该表达式出现在析构函数类的非虚拟析构函数中。如果查找失败或释放函数的定义已删除,则程序的格式不正确。[注意:这确保了与对象的动态类型相对应的解除分配函数可用于删除表达式。-结束注意]


为什么标准要求这样做?我不知道,但你必须找到其他方法来解决你的问题。也许这个线程会很有用:

我更好奇您的用例是否可能不希望
Base
构造函数是虚拟的?为什么需要将
派生的
类的
delete
操作符标记为deleted?你需要解决的实际问题是什么?@Someprogrammerdude这段代码是从我的工作副本中裁剪出来的。我只需要创建一个QDialog的子类,并防止在堆上创建,所以我删除了全局运算符new和运算符delete,然后删除。顺便说一句,msvc2017不需要,因为析构函数必须知道如何取消分配对象,即使您在特定程序中没有使用免费存储。编译器知道,另一个源文件需要
Base*p=new-Derived();删除p
要使其工作,必须将重载的
运算符delete
的知识烘焙到虚拟析构函数中。在进行烘焙时,编译器发现并抱怨删除的
运算符delete
。但失败了。。。请问错误信息是什么?我知道,我的问题很容易解决,只需删除
操作员new
即可。我只是想知道为什么需要
操作员删除
,为什么标准要求这样做。为什么msvc没有抱怨?@libgcc如果msvc在一致性模式下没有抱怨,那就是编译器错误