Only one default?
Yes. Try making two default constructors:
A() = delete;
A(int val = 10) : x(val) {}
And it will immediately result in an error:
error: call of overloaded ‘A()’ is ambiguous
Is the only way to use it (for class A) is:
A() = default;
The definition from cppreference:
A default constructor is a constructor which can be called with no arguments (either defined with an empty parameter list, or with default arguments provided for every parameter).
So, the answer is no, you can write a default constructor with multiple default parameters, but it should be callable as A()
in any context i.e., you should be able to write A object;
with any of the constructors below. All of the following are valid default constructors:
A() = default;
A(int x = 10) {}
A(int x = 10, int y = 10) {}
A(std::initializer_list<T> list = {}) {}
A object; // will work with any of the constructors above
Of course you can use only one of them for a class.
Is there any virtue to such a constructor?
It depends on your needs, your application, your design, whatever. The choice is with you. But personally I wouldn't make a default constructor that takes an initializer_list
or multiple default arguments just because it adds to the confusion. One important point to keep in mind here is that, in my opinion, the default constructor should be very light and ideally should just be an empty function call. The reason for this is that you often end up using your class in a container and this could result in a lot of default constructor calls. If your default constructor is doing a lot of things, then you will pay a performance penalty. Consider:
std::vector<A> vec(1000); // results in 1000 calls to default constructor of A
Can I also declare (and not only define) a constructor and make it default?
No. If you don't provide a definition for a constructor or any function, it will result in an error which usually goes like undefined reference to xxx
. You can still write =default
which is close to what you want.
Also note that following two default constructors are not the same:
A() = default; //1
A() {} //2
1
is a trivial default constructor. You are explicitly telling the compiler to generate a trivial default constructor.
2
is non-trivial user defined constructor.