Reputation: 366
So, I'm asking this question about constructors, but it applies to all member methods that a compiler provides to a class.
I'm a little confused about the default
keyword. What are the restrictions, what are the limitations (only Ctor with no parameters? Only one default?)
and more specifically:
A() = default;
Is it possible to define a constructor, that has an initializer list, as "default"?
Is there any virtue to such a constructor? and if there is, what is the proper syntax to do it?
Can I also define (and not only declare) a constructor and make it default?
class A
{
public:
A() = delete;
A(int val) : x(val) {} // how to make it default?;
private:
int x;
};
int main()
{
A a(2);
}
Upvotes: 1
Views: 2073
Reputation: 9331
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.Upvotes: 2