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