繁体   English   中英

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 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?

为什么这不起作用?

§12.6.2[class.base.init] / p10:

在非委托构造函数中, 可能会调用每个可能构造的类类型子对象的析构函数 (12.4)。 [ 注意:此规定确保在抛出异常时可以为完全构造的子对象调用析构函数(15.2)。 - 结束说明 ]

§12.4[class.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() 这不是完全理想的(因为它给出了链接时错误而不是编译时错误),但它可能会给你你需要的东西。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM