默认构造函数

一个默认的构造函数是一种构造,无需参数调用时。它以它构造的类型命名,并且是它的成员函数(就像所有构造函数一样)。

class C{
    int i;
public:
    // the default constructor definition
    C()
    : i(0){ // member initializer list -- initialize i to 0
        // constructor function body -- can do more complex things here
    }
};

C c1; // calls default constructor of C to create object c1
C c2 = C(); // calls default constructor explicitly
C c3(); // ERROR: this intuitive version is not possible due to "most vexing parse"
C c4{}; // but in C++11 {} CAN be used in a similar way

C c5[2]; // calls default constructor for both array elements
C* c6 = new C[2]; // calls default constructor for both array elements

满足无参数要求的另一种方法是开发人员为所有参数提供默认值:

class D{
    int i;
    int j;
public:
    // also a default constructor (can be called with no parameters)
    D( int i = 0, int j = 42 ) 
    : i(i), j(j){
    }
};

D d; // calls constructor of D with the provided default values for the parameters

在某些情况下(即,开发人员不提供构造函数且没有其他不合格条件),编译器隐式提供一个空的默认构造函数:

class C{
    std::string s; // note: members need to be default constructible themselves
};

C c1; // will succeed -- C has an implicitly defined default constructor

有一些其他类型的构造函数是前面提到的不合格条件之一:

class C{
    int i;
public:
    C( int i ) : i(i){}
};

C c1; // Compile ERROR: C has no (implicitly defined) default constructor

Version < C++ 11

为了防止隐式默认构造函数的创建,一种常见的技术是将其声明为 private(没有定义)。当有人试图使用构造函数时,目的是导致编译错误(这会导致访问私有错误或链接器错误,具体取决于编译器)。

为了确保定义了一个默认构造函数(在功能上类似于隐式构造函数),开发人员可以显式地写一个空构造函数。

Version >= C++ 11

在 C++ 11 中,开发人员还可以使用 delete 关键字来防止编译器提供默认构造函数。

class C{
    int i;
public:
    // default constructor is explicitly deleted
    C() = delete;
};

C c1; // Compile ERROR: C has its default constructor deleted

此外,开发人员也可能明确要求编译器提供默认构造函数。

class C{
    int i;
public:
    // does have automatically generated default constructor (same as implicit one)
    C() = default;

    C( int i ) : i(i){}
};

C c1; // default constructed
C c2( 1 ); // constructed with the int taking constructor 

Version >= C++ 14

你可以使用 <type_traits> 中的 std::is_default_constructible 确定类型是否具有默认构造函数(或者是基本类型):

class C1{ };
class C2{ public: C2(){} };
class C3{ public: C3(int){} };

using std::cout; using std::boolalpha; using std::endl;
using std::is_default_constructible;
cout << boolalpha << is_default_constructible<int>() << endl; // prints true
cout << boolalpha << is_default_constructible<C1>() << endl; // prints true
cout << boolalpha << is_default_constructible<C2>() << endl; // prints true
cout << boolalpha << is_default_constructible<C3>() << endl; // prints false

Version = C++ 11

在 C++ 11 中,仍然可以使用 std::is_default_constructible 的非仿函数版本:

cout << boolalpha << is_default_constructible<C1>::value << endl; // prints true