为何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
相关产品推荐
相关产品推荐

