以自身为参数调用拷贝构造函数时会发生什么?为何对象地址未变?
问题解析
核心误解点
你混淆了对象创建和赋值操作的本质区别:
- 拷贝构造函数的作用是创建全新对象,会为新对象分配独立内存,新对象的地址必然和原对象不同。
- 赋值操作是对已存在的对象进行数据覆盖,不会改变该对象的内存地址——对象的存储位置从它被创建时就固定了。
代码逐行拆解
看你的代码:
class A { public: A(const A& t) { std::cout << "sss" << endl; }; A() {}; }; int main() { A a; std::cout << &a << endl; a = A(a); std::cout << &a << endl; }
A a;:在栈上创建对象a,分配固定内存地址,这个地址从始至终不会改变。A(a):这一步确实调用了拷贝构造函数,创建了一个临时对象,这个临时对象的地址和a完全不同,但你没有打印它的地址,所以看不到差异。a = 临时对象:这是调用编译器自动生成的默认赋值运算符,把临时对象的数据(你的类没有成员变量,实际无内容可拷贝)覆盖到已有的a对象中,a的内存地址还是原来的——赋值不会改变对象的存储位置。
自参数调用拷贝构造的注意事项
- 像
A(a)这种用自身作为参数调用拷贝构造函数,只要参数是const A&(const引用)就是合法的,编译器允许将自身绑定到const引用。如果是非const引用(比如A(A& t)),这种写法会直接编译报错,C++不允许将非const引用绑定到自身的临时对象。 - 若要验证拷贝构造创建新对象的地址变化,可修改代码为:
int main() { A a; std::cout << &a << endl; A b(a); // 用a拷贝构造新对象b std::cout << &b << endl; // 此处b的地址和a完全不同 }
内容的提问来源于stack exchange,提问作者GuangJun Liu
相关产品推荐
相关产品推荐

