特殊情况下拷贝构造函数的调用方式及代码示例解析
拷贝构造函数的调用场景(含你的代码分析)
嘿,咱们来拆解你这个问题——先从你的代码入手,再拓展到拷贝构造函数的特殊调用情况~
首先先把你的代码整理成可编译的完整版本(补全必要的头文件):
#include <iostream> #include <string> using namespace std; class Person { public: Person() { cout << "constructor" << endl; }; Person(istream& a); Person(const Person& a) : name(a.name), address(a.address) { cout << "copy constructor" << endl; } ~Person() { cout << "destructor" << endl; }; private: string name; string address; }; Person::Person(istream& a) { a >> name >> address; cout << "call constructor with istream" << endl; } int main() { Person a = Person(cin); return 0; }
你的代码里的拷贝构造调用情况
你写的Person a = Person(cin);,理论上会触发两步:
- 调用
Person(istream&)构造一个临时的Person对象; - 调用拷贝构造函数,把这个临时对象拷贝给
a。
但你在VS2017里运行可能看不到copy constructor的输出——这是因为编译器做了返回值优化(RVO,Return Value Optimization),直接跳过临时对象的创建,在a的内存空间里直接构造对象,所以拷贝构造函数被省略了。
如果想看到拷贝构造被调用,可以关闭VS的优化选项:
- 右键项目 → 属性 → C/C++ → 优化 → 选择
禁用优化(/Od),再运行就能看到拷贝构造的输出了。
拷贝构造函数的其他特殊调用场景
除了上面这种被优化的情况,还有这些场景一定会(或可能)触发拷贝构造:
- 用已有对象初始化新对象:比如
Person b(a);或者Person b = a;(后者和你的代码不同,这里是用已存在的a初始化b,不是临时对象) - 函数以值传递方式接收对象参数:比如定义
void func(Person p),调用func(a)时,会把a拷贝给形参p,触发拷贝构造 - 函数返回对象(未被优化时):比如
Person createPerson() { return Person(); },如果编译器没做RVO,返回时会拷贝临时对象到调用方 - 对象被插入到容器中:比如
vector<Person> vec; vec.push_back(a);,会把a拷贝到容器的内存空间里 - 用对象初始化智能指针的指向对象(某些情况):比如
shared_ptr<Person> sp(new Person(a));,这里会拷贝a构造新对象
内容的提问来源于stack exchange,提问作者Miralan
相关产品推荐
相关产品推荐

