任何人都可以解释以下 c++ 代码中大括号 () 和大括号 { } 这种奇怪行为背后的机制吗?

Mul*_*ary 0 c++ constructor

详细的阐述有点长,我已经将我面临的问题分解为 3 个“回合”,所以请耐心等待......

对于第一轮,请考虑以下 C++ 代码,该代码没有错误并且行为符合预期:

#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;
}
Run Code Online (Sandbox Code Playgroud)

当我运行代码时,它输出:

Area a= 40
Area b= 12
Area c= 24
Volume d= 240
Volume e= 360
Volume f= 126
Run Code Online (Sandbox Code Playgroud)

分析结果:

  • Area a= 40因为默认构造函数的宽度a设置为 5,长度a设置为 8
  • Area b= 12因为根据参数,宽度b设置为 3,长度b设置为 4
  • Area c= 24由于宽度c被设置3为来自参数,并且由于c缺少长度参数,因此它被设置8为来自类中长度的默认构造函数值rect
  • Volume d= 240因为 recta来自5 x 6类中的默认构造函数rect,并且盒子的高度d来自参数 6
  • Volume e= 360因为 recta来自5 x 6类中的默认构造函数rect,并且 box 的高度e来自类中的默认构造函数box
  • Volume f= 126输出 126,因为 的 矩形f来自2 x 7类中的默认构造函数box,而框的高度e来自类中的默认构造函数box

接下来,对于第 2 轮,将box类构造函数行替换为第 2 轮选项 1:

box(rect a={2}, float c=9) : base(a), height(c){ }

或者通过选项 2:

box(rect a=(2), float c=9) : base(a), height(c){ }

注意从大括号rect a={2}到普通大括号的变化rect a=(2)

现在,运行上面的代码,两个构造函数声明(rect a={2}rect a=(2))将给出以下输出:

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
Run Code Online (Sandbox Code Playgroud)

请注意,第 2 轮中,代码在构造函数声明选项 1 和 2 ( rect a={2}& rect a=(2)) 中给出了相同的输出。

到目前为止,一切都按预期进行。

接下来,对于最后的混乱回合,box用选项 3 替换类构造函数:

box(rect a=(2,7), float c=9) : base(a), height(c){ }

注意 中的普通大括号rect a=(2,7)

其他所有结果都保持不变(因为它们不受更改的影响),除了Volume f,这是一个巨大的504。根据我的观察,编译器选择了:

  • 宽度7,从rect a=(2,7)
  • rect类中默认宽度的长度为 8
  • 高度比box类本身的默认高度高 9

高度的选择是合乎逻辑的,但宽度和长度的选择却令人困惑。

有人能解释一下这背后的机制吗?

我的期望是,第 3 轮的行为应该与第 1 轮完全相同,因为第 2 轮选项 1 和第 2 轮选项 2 的行为相同。

总而言之,我的问题是,将包含另一个类成员的类的构造函数声明为第 1 轮大括号和第 3 轮普通大括号时,是什么导致了差异?

Rem*_*eau 6

rect a={2,7}rect使用两个输入值调用构造函数,w=2并且l=7

rect a=(2,7)将首先调用逗号运算符(在本例中将返回7),然后rect使用一个输入值 调用构造函数w=7,使l参数使用其默认值。