为何存在拷贝构造函数时声明对象赋值不调用参数化构造函数反而报错
问题原因解释
首先明确一个基础概念:Test x = 6 属于拷贝初始化,而非直接初始化,执行逻辑分为两步:
- 隐式调用参数化构造函数
Test(int a),将字面量6转换为Test类型的临时右值对象 - 调用拷贝构造函数,用这个临时对象初始化
x
情况1正常运行的原因
当你没有自定义拷贝构造函数时,编译器会自动生成默认拷贝构造函数,签名为Test(const Test&)。C++标准允许临时右值绑定到const左值引用,因此拷贝构造的参数匹配成功,代码可以正常运行。同时编译器通常会触发复制消除优化,直接跳过拷贝步骤,用参数化构造函数初始化x,不会产生额外性能开销。
情况2报错的原因
你自定义的拷贝构造函数签名为Test(Test&),参数是非const左值引用。C++标准明确禁止临时右值绑定到非const左值引用(避免无意义地修改生命周期极短的临时对象),因此第二步拷贝构造的参数匹配失败,直接抛出你看到的绑定错误。
修复方案
- 方案1:修改拷贝构造函数的参数为const左值引用,符合通用的拷贝构造函数规范:
Test(const Test &b){ this->a = b.a; }
- 方案2:使用直接初始化语法,跳过临时对象构造和拷贝的步骤:
Test x(6); // 或者C++11及以后用 Test x{6};
- 方案3:给类添加接受右值引用的移动构造函数:
Test(Test &&b){ this->a = b.a; }
内容的提问来源于stack exchange,提问作者Parag Jain
相关产品推荐
相关产品推荐

