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