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

为何HasPtr对象p2=p1调用拷贝构造函数而非拷贝赋值运算符?何时触发拷贝赋值?

拷贝构造函数与拷贝赋值运算符的调用场景解析

先看给出的代码:

class HasPtr
{
public:
    HasPtr(const HasPtr& h) :ps(new string(*h.ps)), i(h.i) { cout << "Copy Constructor" << endl; }
    HasPtr& operator=(const HasPtr& hp) {
        ps = new string(*hp.ps); 
        i = hp.i; 
        cout << "Copy Assignment Constructor" << endl;
        // 补充:原代码遗漏了return语句,拷贝赋值运算符必须返回自身引用以支持链式赋值
        return *this;
    }
    HasPtr(const string& s = string()) :ps(new string(s)), i(0) {};
private:
    string* ps;
    int i;
};

int main()
{
    HasPtr p1;
    HasPtr p2 = p1;
    return 0;
}

为什么HasPtr p2 = p1;调用拷贝构造函数?

这行代码是初始化新对象的操作,而非赋值。C++中,当你通过=语法创建一个完全新的对象(p2在此之前不存在,这是它的首次创建),属于拷贝初始化范畴,编译器会调用拷贝构造函数来完成这个新对象的初始化工作。

核心区别:只要是创建新对象的过程,就会触发构造函数(这里是拷贝构造);赋值运算符的调用前提是左边的对象已经完成构造、处于已存在状态。

拷贝赋值运算符的调用场景

拷贝赋值运算符operator=会在已有对象被同类型对象赋值时触发,常见场景包括:

  • 两个已构造完成的对象之间的直接赋值:HasPtr p1, p2; p2 = p1;
  • 已有对象接收函数返回的对象:HasPtr get_obj(); HasPtr p; p = get_obj();
  • 循环或逻辑中重复给同一个已有对象赋值:
    HasPtr p;
    for (int i = 0; i < 5; ++i) {
        p = HasPtr(to_string(i)); // 每次循环都是给已存在的p赋值新对象
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 12:47:20