C++11 在派生 class 中删除的析构函数
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 test.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'
(代码上面有一行emply,所以这些都是一个。抱歉)
我有一些特殊的类(一个基类和许多派生类),出于性能原因,它们总是分配在像内存区域这样的堆栈中。
他们没有得到任何析构函数调用(并且按照设计他们不需要)。如果我之后的某个程序员决定他真的需要在里面放一个向量,这可能会很糟糕。(内存泄漏,这些类大量产生并且存在一些函数调用,哎哟)
我尝试的是使用 C++11 删除的析构函数。
我的问题是:
- 为什么这不起作用?
- 关于如何在类中禁止析构函数或非 POD 有更好的想法吗?
Why is this not working?
§12.6.2 [class.base.init]/p10:
In a non-delegating constructor, the destructor for each potentially constructed subobject of class type is potentially invoked (12.4). [ Note: This provision ensures that destructors can be called for fully-constructed sub-objects in case an exception is thrown (15.2). — end note ]
§12.4 [class.dtor]/p11:
[...] A program is ill-formed if a destructor that is potentially invoked is deleted or not accessible from the context of the invocation.
如果在任何子对象的构造过程中抛出异常,编译器将调用已构造的基 类 和数据成员的析构函数,因此 D
的构造函数需要一个非删除的, B
.
的可访问析构函数
Any better ideas how to forbid destructors or non-PODs inside the class?
在你的情况下,使析构函数 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 析构函数:
class B {
int i;
public:
B(int param) : i(param) {}
~B();
};
通过这样做,您现有的代码将起作用,并且任何试图破坏 B
实例的程序都将失败 link,因为 ~B()
未定义。这并不完全理想(因为它会给出 link 时错误而不是编译时错误),但它可能会满足您的需要。
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 test.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'
(代码上面有一行emply,所以这些都是一个。抱歉)
我有一些特殊的类(一个基类和许多派生类),出于性能原因,它们总是分配在像内存区域这样的堆栈中。 他们没有得到任何析构函数调用(并且按照设计他们不需要)。如果我之后的某个程序员决定他真的需要在里面放一个向量,这可能会很糟糕。(内存泄漏,这些类大量产生并且存在一些函数调用,哎哟)
我尝试的是使用 C++11 删除的析构函数。 我的问题是:
- 为什么这不起作用?
- 关于如何在类中禁止析构函数或非 POD 有更好的想法吗?
Why is this not working?
§12.6.2 [class.base.init]/p10:
In a non-delegating constructor, the destructor for each potentially constructed subobject of class type is potentially invoked (12.4). [ Note: This provision ensures that destructors can be called for fully-constructed sub-objects in case an exception is thrown (15.2). — end note ]
§12.4 [class.dtor]/p11:
[...] A program is ill-formed if a destructor that is potentially invoked is deleted or not accessible from the context of the invocation.
如果在任何子对象的构造过程中抛出异常,编译器将调用已构造的基 类 和数据成员的析构函数,因此 D
的构造函数需要一个非删除的, B
.
Any better ideas how to forbid destructors or non-PODs inside the class?
在你的情况下,使析构函数 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 析构函数:
class B {
int i;
public:
B(int param) : i(param) {}
~B();
};
通过这样做,您现有的代码将起作用,并且任何试图破坏 B
实例的程序都将失败 link,因为 ~B()
未定义。这并不完全理想(因为它会给出 link 时错误而不是编译时错误),但它可能会满足您的需要。