📜  c++ 默认构造函数删除 - C++ (1)

📅  最后修改于: 2023-12-03 15:29:53.174000             🧑  作者: Mango

C++ 默认构造函数删除

C++11中,对于以下情况,将会自动删除默认构造函数:

  • 类中含有const或引用类型的成员变量,因为这种类型的变量必须在构造函数初始值列表中初始化,而默认构造函数没有初始值列表。
  • 类中含有子对象,且该子对象的类中也定义了删除了默认构造函数,因为在构造函数中必须对子对象进行初始化。
  • 类的构造函数都被声明为explict,此时默认构造函数不应该存在。

下面是一个例子:

#include <iostream>
using namespace std;

class Test {
public:
    Test() = default;  // 显示声明默认构造函数
    Test(int x) { cout << "Test(int x)" << endl; }
    Test(double y) { cout << "Test(double y)" << endl; }
};

int main() {
    Test t1;  // 会输出Test(int x)
    Test t2 = 1;  // 会输出Test(int x)
    Test t3 = 1.0;  // 会输出Test(double y)
    return 0;
}

在上述代码中,Test类中定义了一个整型成员变量和一个双精度浮点型成员变量。由于整型变量可以默认初始化为0,所以在默认构造函数中可以不对其进行初始化。但是,浮点型变量需要在构造函数的初始值列表中指定初值,因为默认情况下它不会被初始化为0。所以,如果没有进行删除操作,在编译时,Test类将有两个构造函数,一是默认构造函数,另一个是接受双精度浮点型参数的构造函数。然而,由于默认构造函数不能对成员变量进行初始化,所以在该例中,需要显式声明一个默认构造函数来解决这个问题。

如果在类定义中添加了一个常量成员变量,则会自动删除默认构造函数。例如:

#include <iostream>
using namespace std;

class Test {
public:
    Test() = default;
private:
    const int ci;
};

int main() {
    Test t;  // 编译错误:试图使用被删除的函数 “Test ::Test ()”
    return 0;
}

在上述代码中,由于Test类中含有一个const类型的成员变量,因此在编译时,会发现默认构造函数被删除了,无法使用。

为了防止默认构造函数的自动删除,也可以显式声明一个删除默认构造函数的语句,如下所示:

class Test {
public:
    Test() = delete;  // 显式声明删除默认构造函数
private:
    const int ci;
};

在此例中,显式声明了一个删除默认构造函数的语句,即Test() = delete;。因此,在编译时,如果有代码试图调用默认构造函数,则会收到编译错误的消息。

以上就是有关C++的默认构造函数被删除的介绍。在使用const或引用类型的成员变量,或定义有常量成员变量的类时,需要注意默认构造函数的自动删除原则。如果需要保留默认构造函数,必须在类定义中显式定义一个默认构造函数。如果需要删除默认构造函数,也可以在类定义中显式声明一个删除默认构造函数的语句。