C++初始化类数组成员时为何未触发Sample类拷贝构造函数
现象成因
你观察到的Sample拷贝构造不触发的现象,是C++列表初始化的标准行为,核心逻辑如下:
- 你在
user构造函数初始化列表中写的newObj{ {1,1,{0,0,100,100}} , {2,2, {0,0,100,100}} }属于数组的直接列表初始化:编译器会针对数组的两个元素,分别用内层花括号的3个参数(两个int值、一个临时构造的Point对象)直接匹配Sample类的三参数构造函数,在数组元素的对应内存位置原地构造对象,全程不会先构造临时Sample对象再执行拷贝操作,因此Sample的拷贝构造函数完全不会被调用。 - 日志中出现的
Point拷贝构造调用,和Sample的拷贝逻辑没有关系:Sample构造函数的第三个参数是const Point& p,会直接绑定花括号中临时构造的匿名Point对象;在Sample的初始化列表中执行pointObj(p)时,会调用Point的拷贝构造来初始化类内的Point成员变量,因此会打印Point拷贝构造的日志。 - 你的代码中已经将
Sample的所有拷贝构造重载都标记为= delete,代码依然可以正常编译运行,这本身就是初始化过程未调用Sample拷贝构造的直接证据——如果初始化流程中存在Sample拷贝操作,编译器会直接抛出「调用已删除函数」的编译错误,程序根本无法运行。
常见认知误区:不少开发者认为列表初始化数组元素时,会先构造临时对象再拷贝到数组内存位置,这个认知不符合C++11及之后的标准要求:当列表中的参数可以直接匹配目标类型的构造函数时,编译器会直接在目标内存位置原地构造对象,强制省略拷贝/移动步骤,不需要拷贝/移动构造函数处于可访问状态。
内容的提问来源于stack exchange,提问作者loyola
相关产品推荐
相关产品推荐

