預設建構函式

一個預設的建構函式是一種構造,無需引數呼叫時。它以它構造的型別命名,並且是它的成員函式(就像所有建構函式一樣)。

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