C++构造函数匹配疑问:B1 b4 = b2为何触发A参数构造函数?
问题解答
一、为什么B1 b3 = b1;没有输出?
咱们先唠这个问题:当你写B1 b3 = b1;时,这属于拷贝初始化操作。因为你没给B1自定义参数为const B1&的拷贝构造函数,C++编译器会自动帮你生成一个默认的拷贝构造函数。这个默认构造函数只会干一件事——把b1里的所有成员(包括从A继承来的m_a,还有B1自己的m_b)逐位拷贝到b3里,它不会执行任何额外的输出语句,所以这一行自然不会产生打印内容。
说白了就是:编译器偷偷给你生成了个没输出的拷贝构造函数,你自然看不到任何东西。
二、为什么B1 b4 = b2;会触发接收A的构造函数?
这个问题要结合隐式向上转型和对象切片来理解,咱们一步步拆:
首先,
B2是A的public派生类,根据C++规则,派生类对象可以被隐式转换成基类对象——这个过程就是对象切片:只保留b2中属于基类A的部分(也就是m_a成员),把B2自己的m_b给“切”掉了。再看
B1的构造函数,它有一个接受const A&参数的版本。当你写B1 b4 = b2;时,编译器发现没有直接接受B2的构造函数,就会尝试找可行的转换路径:先把b2隐式转成A类型的临时对象,再用这个临时对象去调用B1的B1(const A& a)构造函数,这就触发了该构造函数里的输出语句,也就是你看到的B1_constructor_with_a_parameter_A。
这个过程等价于手动拆解成两步:
A temp_a = b2; // 隐式转换+对象切片,仅保留b2的A部分 B1 b4(temp_a); // 调用B1的A参数构造函数,输出对应内容
总结一下:因为B2能隐式转成A,而B1刚好有接受A的构造函数,所以编译器走了这条转换路径,同时这个过程中发生了对象切片。
内容的提问来源于stack exchange,提问作者Schytheron
相关产品推荐
相关产品推荐

