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

C++11: Can I create a field whose type has a deleted destructor?

本文关键字:删除 析构函数 字段 类型 一个 创建 我可以 C++11      更新时间:2023-10-16

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

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

然而,当尝试实例化父类的构造函数时,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

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

您的问题不正确,构造函数被定义为已删除,因为该类成员的析构函数被定义为删除,但是,您只需编写

DeletedDtor* d = new DeletedDtor();

一切都会很好(当然不需要删除),所以gcc和clang都是正确的。

n3376 12.1/8

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

--任何直接或虚拟基类或非静态数据成员都有一个带有已删除的析构函数的类型或无法从默认默认构造函数访问

我没有实际C++标准的副本,但最新的工作草案说:

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

一种隐式或显式引用已删除函数的程序,除了宣布它之外,它是不正规的。[…]

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

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

class MyClass
{
  public:
    MyClass() = default;
  private:
    DeletedDtor* a;
};