C++中复制构造函数不可用时为何不调用拷贝赋值运算符?
核心原因:C++ 中「初始化」和「赋值」是完全独立的语义,= 在不同场景下作用完全不同
1. 两个场景的语义差异
Obj o2 = o1;属于对象初始化阶段:这个语句的核心是创建全新的对象o2,只要是新对象创建流程,必然要调用构造函数完成初始化。这里的=只是初始化语法的标记,作用是告诉编译器用已存在的o1作为入参调用拷贝构造函数,和你写Obj o2(o1);的语义完全等价,不属于赋值操作。Obj o1; Obj o2; o2 = o1;属于赋值阶段:前两行已经分别通过默认构造函数完成了o1、o2两个对象的初始化,两个对象都已经是完整存在的实例,第三行的=才是对已存在对象的赋值操作,会触发拷贝赋值运算符的调用。
2. 为什么删除拷贝构造函数会编译报错
如果类显式删除了拷贝构造函数(Obj(const Obj&) = delete;),Obj o2 = o1; 依赖拷贝构造函数完成初始化的逻辑就找不到可用的函数,自然会编译报错。哪怕你实现了拷贝赋值运算符也没用,因为语法层面不会走到赋值逻辑的分支。
3. 该场景下的 = 运算符是否被重载了
这个场景下的 = 根本不会触发赋值运算符的调用,无论你有没有重载类的赋值运算符,都不会用到。它只是 C++ 初始化语法的一个符号标记,和作为二元运算符的赋值 = 是完全不同的语法元素。
内容的提问来源于stack exchange,提问作者pauk
相关产品推荐
相关产品推荐

