You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中Class(const Class& c)与Class(Class& c)构造函数的区别及调用时机

非const左值引用构造函数 vs const左值拷贝构造函数的调用时机

嘿,这个问题问得挺到位的,咱们一步一步来理清楚~

首先明确:你定义的Class(Class& c)是一个接受非const左值引用的构造函数,它和标准的const Class&拷贝构造函数是重载关系。标准拷贝构造函数(const Class&版本)能覆盖绝大多数拷贝场景,但这个非const版本的构造函数,只会在特定的、更“精确匹配”的场景下被调用。

什么时候会调用Class(Class& c)?

主要有三类核心场景:

1. 传递非常量左值对象时,编译器优先匹配更精确的重载

当你用一个非const的左值初始化新对象时,如果同时存在const Class&和Class&两个构造函数,编译器会优先选择不需要添加const限定的那个——也就是Class(Class& c)。

修正测试代码就能看到区别:

Class c; // 输出:running Class()...
Class cc(c); // 此时会调用Class(Class& c),因为c是非常量左值,非const版本匹配度更高

(你之前的测试例子里输出了const版本,大概率是代码笔误或者测试时的小疏漏,实际编译运行的话,非const左值会优先触发非const引用的构造函数)

2. 显式指定绑定非const左值引用

如果你通过强制类型转换,把对象转成非const左值引用,编译器就会精准匹配对应的构造函数:

Class c;
Class cc(static_cast<Class&>(c)); // 显式转成非const引用,调用Class(Class& c)

3. 接收返回非const左值的函数结果

如果有函数返回非const左值引用,用它初始化新对象时,也会触发这个构造函数:

Class& get_non_const_obj() {
    static Class obj;
    return obj;
}

Class d(get_non_const_obj()); // 调用Class(Class& c)

什么时候绝对不会调用Class(Class& c)?

这个构造函数的参数是非const左值引用,所以以下场景完全无法匹配:

  • 用const常量对象初始化新对象:const Class c_const; Class cc(c_const); —— 只能调用const Class&版本
  • 用**临时对象(右值)**初始化新对象:Class cc(Class()); —— 临时对象是右值,无法绑定到非const左值引用,会调用const Class&版本
  • 用volatile对象初始化新对象:同样无法匹配非const引用的构造函数

额外提醒

标准意义上的“拷贝构造函数”指的是Class(const Class&)(C11之前)或加上移动构造Class(Class&&)(C11及以后)。你定义的Class(Class&)是自定义的重载构造函数,它不属于标准拷贝构造函数的范畴——比如编译器生成默认拷贝构造时,只会生成const Class&版本,不会生成这个非const版本。

内容的提问来源于stack exchange,提问作者Land

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:13:22