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

以自身为参数调用拷贝构造函数时会发生什么?为何对象地址未变?

问题解析

核心误解点

你混淆了对象创建和赋值操作的本质区别:

  • 拷贝构造函数的作用是创建全新对象,会为新对象分配独立内存,新对象的地址必然和原对象不同。
  • 赋值操作是对已存在的对象进行数据覆盖,不会改变该对象的内存地址——对象的存储位置从它被创建时就固定了。

代码逐行拆解

看你的代码:

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;
}
  1. A a;:在栈上创建对象a,分配固定内存地址,这个地址从始至终不会改变。
  2. A(a):这一步确实调用了拷贝构造函数,创建了一个临时对象,这个临时对象的地址和a完全不同,但你没有打印它的地址,所以看不到差异。
  3. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 23:50:44