Home > OS >  can anyone explain the mechanics behind this weird behavior of braces ( ) and curly braces { } in th
can anyone explain the mechanics behind this weird behavior of braces ( ) and curly braces { } in th

Time:01-08

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 of a is set to 5 and length of a is set to 8 by the default constructor
  • Area b= 12 since width of b is set to 3 and length of b is set to 4 from the arguments
  • Area c= 24 since width of c is set to 3 from the argument, and since argument for length of c is missing, it is set to 8 from the default constructor value for length in class rect
  • Volume d= 240 since rect a is 5 x 6 from default constructor in class rect, and height of box d is 6 from argument
  • Volume e= 360 since rect a is 5 x 6 from default constructor in class rect, and height of box e is 9 from default constructor in class box
  • Volume f= 126 outputs 126 since rect of f is 2 x 7 from default constructor in class box, and height of box e is 9 from default constructor in class box

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.

  • Related