A default constructor is a type of constructor that requires no parameters when called. It is named after the type it constructs and is a member function of it (as all constructors are).
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
Another way to satisfy the "no parameters" requirement is for the developer to provide default values for all parameters:
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
Under some circumstances (i.e., the developer provides no constructors and there are no other disqualifying conditions), the compiler implicitly provides an empty default constructor:
class C{
std::string s; // note: members need to be default constructible themselves
};
C c1; // will succeed -- C has an implicitly defined default constructor
Having some other type of constructor is one of the disqualifying conditions mentioned earlier:
class C{
int i;
public:
C( int i ) : i(i){}
};
C c1; // Compile ERROR: C has no (implicitly defined) default constructor
To prevent implicit default constructor creation, a common technique is to declare it as private
(with no definition). The intention is to cause a compile error when someone tries to use the constructor (this either results in an Access to private error or a linker error, depending on the compiler).
To be sure a default constructor (functionally similar to the implicit one) is defined, a developer could write an empty one explicitly.
In C++11, a developer can also use the delete
keyword to prevent the compiler from providing a default constructor.
class C{
int i;
public:
// default constructor is explicitly deleted
C() = delete;
};
C c1; // Compile ERROR: C has its default constructor deleted
Furthermore, a developer may also be explicit about wanting the compiler to provide a default constructor.
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
You can determine whether a type has a default constructor (or is a primitive type) using std::is_default_constructible
from <type_traits>
:
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
In C++11, it is still possible to use the non-functor version of std::is_default_constructible
:
cout << boolalpha << is_default_constructible<C1>::value << endl; // prints true