派生类中C++11 已删除的析构函数
C++11's deleted destructor in derived class
class B {
int i;
public:
B(int param) : i(param) {}
~B() = delete;
};
class D : public B {
int i2;
public:
D(int p1, int p2) : B(p1), i2(p2) {}
~D() = delete;
};
int main() {
B* instance = new D(1,2);
return 0;
}
CL测试.cpp:
Microsoft (R) C/C++ Optimizing Compiler Version 18.00.31101 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
test.cpp
test.cpp(11) : error C2280: 'B::~B(void)' : attempting to reference a deleted function
test.cpp(6) : see declaration of 'B::~B'
(代码上方有一行,所以这些是一次性的,对不起)
我有一些特殊的类(一个基础和许多派生的),出于性能原因,它们总是在像内存竞技场这样的堆栈中分配。它们不会收到任何析构函数调用(并且根据设计,它们不需要)。如果在我之后的某个程序员决定他真的需要在里面放一个向量,这可能会很糟糕。(内存泄漏,这些类大量生成并存在一些函数调用,哎哟)
我尝试的是使用 C++11 删除的析构函数。我的问题是:
- 为什么这不起作用?
- 有什么更好的想法如何在类中禁止析构函数或非 POD 吗?
为什么这不起作用?
§12.6.2 [class.base.init]/p10:
在非委托构造函数中,可能会调用类类型的每个潜在构造子对象的析构函数 (12.4)。[注意:此规定确保在引发异常时可以为完全构造的子对象调用析构函数(15.2)。
§12.4 [类.dtor]/p11:
[...]如果可能调用的析构函数被删除或无法从调用上下文中访问,则程序格式不正确。
如果在构造任何子对象期间引发异常,编译器将调用已构造的基类和数据成员的析构函数,因此D
的构造函数需要一个未删除的、可访问的 B
析构函数。
有什么更好的想法如何在类中禁止析构函数或非 POD 吗?
在您的情况下,使析构函数protected
析构函数应该可以工作:
class B {
int i;
public:
B(int param) : i(param) {}
protected:
~B() {}
};
class D : public B {
int i2;
public:
D(int p1, int p2) : B(p1), i2(p2) {}
protected:
~D() {}
};
Piotr S 已经解释了为什么你现有的代码无效。 这是一个替代解决方案。
可以声明(但不能定义)基类析构函数:
class B {
int i;
public:
B(int param) : i(param) {}
~B();
};
通过这样做,您现有的代码将起作用,并且任何试图销毁B
实例的程序都将无法链接,因为未定义~B()
。 这并不完全理想(因为它给出了链接时错误而不是编译时错误),但它可能会为您提供所需的内容。
相关文章:
- MSVC 编译器/链接器何时合成标量/矢量删除析构函数
- 如果引用应该保留,不删除析构函数中的指针会导致内存泄漏吗?
- 删除析构函数C++中的指针
- bad_alloc::'标量删除析构函数'(无符号整数)当我尝试创建矢量 470MB 大小时
- 这是删除析构函数中的数组的正确方法吗?
- 尽管使用了 boost::scoped_ptr,我们是否应该删除析构函数中成员的指针
- 调用remove()删除析构函数中的文件是否安全
- 当存储在std::vector属性中时,我可以删除析构函数中的指针吗
- 删除析构函数中的(这个)指针
- C++ 删除析构函数中的向量类成员内存
- 删除析构函数中的指针和映射
- 尝试删除析构函数中已删除的指针
- 为什么允许我声明一个带有已删除析构函数的对象
- 为什么在删除析构函数时调用析构函数,如果未删除则不调用析构函数?
- 删除析构函数的意义何在
- std::istream子类:删除析构函数中的streambuf
- 如何安全地删除析构函数中的线程指针
- 标量删除析构函数问题
- C++11:我可以创建一个类型具有已删除析构函数的字段吗
- 为什么在 VC 中,'delete' 和 'delete []' 都使用标量删除析构函数?