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 删除的析构函数。 我的问题是:

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 时错误而不是编译时错误),但它可能会满足您的需要。