Context
According to the tutorial, if a class defines a default constructor Rectangle();
, it'sinvoked via:
int main () {
Rectangle recta; // valid - default constructor
Rectangle rectb(); // valid - but not a default constructor
Rectangle rectc{}; // valid - default constructor
}
It is said that the second call is a "function declaration", so its interpreted by the compiler as some function that returns an object of type Rectangle
. Yet in the subsequent sections of that same tutorial, it refers to Rectangle();
as a default constructor.
Question(s)
So this is a two part question:
- Why are default constructors defined with
()
if calling with()
does not even invoke them? - Why does the use of
{}
invoke the default constructor if defined with()
?
Thoughts/Examples
W.R.T the first item, it seems contradictory that the default constructor definition must be either:
- Completely omitted, or
- Defined with empty parenthesis
Yet calling with empty parenthesis does not invoke the default constructor. The best that I can reason is that the compiler interprets the call to rectb()
as some kind of "inline" function definition that returns an object of type Rectangle
; because of this, if the default constructor had member assignment in it, this newly returned object would not have any members assigned and would all be NULL
(or so I believe).
Now to expand the confusion with a detailed example:
#include <iostream>
using namespace std;
class Circle
{
public:
Circle(); // M1
Circle(float r); // M2
};
Circle::Circle()
{
cout << "default constructor" << endl;
}
Circle::Circle(float r)
{
cout << "custom constructor" << endl;
}
int main() {
Circle c1(1.0); // calls M2
Circle c2(); // does not call M1
return 0;
}
// Outputs
"custom constructor"
0
So if the compiler interprets a line such as Circle c2();
as a newly declared function returning type Circle
, why does it not do that for Circle c1(1.0);
and is instead able to find a matching constructor?
W.R.T. the second item, I believe this is the result of a C++11 design implementation that enables to compiler to handle value-initialization from what I've read. Since it uses {}
and not ()
the compiler does not parse this as a function declaration.
References
Now while I am researching this, the other questions I have found include:
Expands on something called the "most vexing parse" in C++, surrounding how Circle c2();
is treated as a function declaration as noted. However, the question (#1) I am asking expands on this, namely why are what appear to be two function declarations treated differently despite having definitions within the class?
Marked as a duplicate of the previous question, but with examples aligned to this post.