The detail is a little bit long to formulate, and I have broken down the problem I'm facing into 3 "rounds", so bear with me...
For the first round, consider the following C code, which is error-free and one that behaves as expected:
#include <iostream>
using namespace std;
class rect{
float width;
float length;
public:
rect( float w = 5, float l=8 ) : width(w), length(l) {}
float area(){return width * length;}
};
class box{
rect base;
float height;
public:
box(rect a={2,7}, float c=9) : base(a), height(c){ } //round 1
//box(rect a={2}, float c=9) : base(a), height(c){ } //round 2 option 1
//box(rect a=(2), float c=9) : base(a), height(c){ } //round 2 option 2
//box(rect a=(2,7), float c=9) : base(a), height(c){ } //round 3
float volume(){return base.area() * height;}
};
int main(){
rect a;
cout<<"Area a= "<<a.area()<<endl;
rect b(3,4);
cout<<"Area b= "<<b.area()<<endl;
rect c(3);
cout<<"Area c= "<<c.area()<<endl;
box d(a,6);
cout<<"Volume d= "<<d.volume()<<endl;
box e(a);
cout<<"Volume e= "<<e.volume()<<endl;
box f;
cout<<"Volume f= "<<f.volume()<<endl;
return 0;
}
When I run the code, it outputs:
Area a= 40
Area b= 12
Area c= 24
Volume d= 240
Volume e= 360
Volume f= 126
Analyzing the result:
Area a= 40
since width ofa
is set to 5 and length ofa
is set to 8 by the default constructorArea b= 12
since width ofb
is set to 3 and length ofb
is set to 4 from the argumentsArea c= 24
since width ofc
is set to3
from the argument, and since argument for length ofc
is missing, it is set to8
from the default constructor value for length in classrect
Volume d= 240
since recta
is5 x 6
from default constructor in classrect
, and height of boxd
is 6 from argumentVolume e= 360
since recta
is5 x 6
from default constructor in classrect
, and height of boxe
is 9 from default constructor in classbox
Volume f= 126
outputs 126 since rect off
is2 x 7
from default constructor in classbox
, and height of boxe
is 9 from default constructor in classbox
Next, for round 2, replace the box
class constructor line by round 2 option 1:
box(rect a={2}, float c=9) : base(a), height(c){ }
Or by option 2:
box(rect a=(2), float c=9) : base(a), height(c){ }
Note the change from curly brace in rect a={2}
to normal braces rect a=(2)
Now, running the above code, both constructor declarations (rect a={2}
and rect a=(2)
) will give the following output:
Area a= 40 //same logic as in round 1
Area b= 12 //same logic as in round 1
Area c= 24 //same logic as in round 1
Volume d= 240 //same logic as in round 1
Volume e= 360 //same logic as in round 1
Volume f= 126 //output changed because width for rect of f is 2 from default constructor in class box
// since length default value in class a is missing, length for rect of f is set to 8 from default constructor in class rect
// height of box e is 9 from default constructor in class box
Note for round 2, the code gives the same output in both constructor declarations options 1 and 2 (rect a={2}
& rect a=(2)
).
So far, everything is working as it should.
Next, for the final and mayhem round, replace the box
class constructor by option 3:
box(rect a=(2,7), float c=9) : base(a), height(c){ }
Note the normal braces in rect a=(2,7)
.
Every other result stays the same (because they are not affected by the change) except for Volume f
, which is a whopping 504
. By my observation, the compiler has chosen:
- width 7, from
rect a=(2,7)
- length 8 from default width in
rect
class - height 9 from default height from
box
class itself
The choice for height is logical, but the choice for width and length is confusing.
Can anybody explain the mechanics behind this?
My expectation was, round 3 should behave exactly as round 1, since round 2 option 1 & round 2 option 2 are behaving the same.
My question in summary is, what brought about the difference declaring a constructor for a class containing another class member as round 1 curly braces and as round 3 normal braces?
CodePudding user response:
rect a={2,7}
will invoke the rect
constructor with two input values, w=2
and l=7
.
rect a=(2,7)
will first invoke the comma operator (which in this case will return 7
), and then will invoke the rect
constructor with one input value, w=7
, leaving the l
parameter to use its default value.