C++ C++;11:我可以创建一个类型具有已删除析构函数的字段吗?

C++ C++;11:我可以创建一个类型具有已删除析构函数的字段吗?,c++,c++11,C++,C++11,我有一个类型,其析构函数已被显式删除;我想使该类型的实例成为另一个类的成员 我的期望是,如果没有尝试删除包含类的实例(即,包含类的析构函数将无效),那么应该可以 但是,当试图实例化父类的构造函数时,clang(v3.3)和g++(v4.6.3)都会给出一个错误 例如: class DeletedDtor { public: DeletedDtor() {} ~DeletedDtor() = delete; }; class MyClass { public:

我有一个类型,其析构函数已被显式删除;我想使该类型的实例成为另一个类的成员

我的期望是,如果没有尝试删除包含类的实例(即,包含类的析构函数将无效),那么应该可以

但是,当试图实例化父类的构造函数时,clang(v3.3)和g++(v4.6.3)都会给出一个错误

例如:

class DeletedDtor 
{
  public:
    DeletedDtor() {}
    ~DeletedDtor() = delete;
};

class MyClass
{
  public:
    MyClass() = default;
    ~MyClass() = delete;

  private:
    DeletedDtor a;
};

int main() {
    MyClass *p = new MyClass();
}
在g++下,这将给出:

test.cpp: In function ‘int main()’:
test.cpp:19:30: error: use of deleted function ‘MyClass::MyClass()’
test.cpp:11:5: error: ‘MyClass::MyClass()’ is implicitly deleted because the default definition would be ill-formed:
test.cpp:11:5: error: use of deleted function ‘DeletedDtor::~DeletedDtor()’
test.cpp:5:5: error: declared here
自己定义MyClass构造函数,而不是让它采用默认实现,也无助于:

class DeletedDtor 
{
  public:
    DeletedDtor() {}
    ~DeletedDtor() = delete;
};

class MyClass
{
  public:
    MyClass();
    ~MyClass() = delete;

  private:
    DeletedDtor a;
};

MyClass::MyClass() : a() {}

int main() {
    MyClass *p = new MyClass();
}
这会导致编译错误:

test2.cpp: In constructor ‘MyClass::MyClass()’:
test2.cpp:18:24: error: use of deleted function ‘DeletedDtor::~DeletedDtor()’
test2.cpp:5:5: error: declared here

不能保留已删除析构函数的类的实例。但是您可以在
MyClass
中保留指向
deletedTor
的指针:

class MyClass
{
  public:
    MyClass() = default;

  private:
    DeletedDtor* a;
};

您的问题是不正确的,构造函数被定义为deleted,因为这个类的成员的析构函数被定义为deleted,然而,您只需编写

DeletedDtor* d = new DeletedDtor();
所有这些都可以正常工作(当然没有删除),所以gcc和clang都是正确的

n3376 12.1/8

A. 类X的默认构造函数定义为已删除,如果:

-任何直接或虚拟基类或非静态数据成员的类型具有已删除的析构函数
或默认缺省构造函数无法访问。< /P> < /P> < P>我没有实际C++标准的副本,但最新的工作草案说:

8.4.3/2
[dcl.fct.def.delete]

隐式或显式引用已删除函数的程序, 除了声明它,它的格式是错误的。 [……]


当一个对象被析构函数时,任何成员对象的析构函数都会被隐式调用,即使您没有销毁任何对象,仍然会创建一个引用其成员析构函数的默认析构函数。基于此,我认为您得到的错误似乎是正确的。

这种行为的一些基本原理:存在一种情况,即在包含对象的析构函数之外自动调用成员对象的析构函数:以防包含对象的构造函数抛出(中的某些内容)。在构造函数退出之前,已构造成员和基类子对象的析构函数将按与构造相反的顺序调用。

代码和错误消息中的类名不匹配。请澄清。抱歉,错误的c&p(你可能已经注意到了这一点)明确删除
MyClass
的析构函数也无济于事。我想知道是否有删除析构函数的用例…@jrok确保usageI类型上的内存泄漏非常有用,但这并不能回答问题。问题是关于析构函数,而不是构造函数。这回答了问题的措辞,但你也能回答明显的后续问题:当你试图自己定义一个
MyClass()
构造函数时,为什么会出现基本相同的错误?@leftaroundabout情况不同。@ForEveR,谢谢,这是一个很好的答案。但是,正如LeftRoundound所说,它并没有完全回答我是否可以删除其析构函数的字段的问题,因为如果我为MyClass定义自己的构造函数,我(至少)会遇到一个非常类似的问题。我认为这不是问题所在。显式删除MyClass的析构函数在这里对我没有帮助。我更新了这个问题来说明这一点。这很有意义!非常感谢。