以下情形会发生对象的拷贝(根据原有的对象,创建一个新的对象):
使用原有的对象,为一个新的对象进行初始化(Initialization)
Person baby_a("Fred");
Person baby_b(baby_a); // 使用对象 baby_a 初始化对象 baby_b,发生对象的拷贝
Person baby_c = baby_a; // 同上
函数的传值调用(Call By Value)
void func(Currency p) {...}
Currency bucks(100, 0); // 初始化一个对象
func(bucks); // 这里是传值调用,发生对象的拷贝
函数返回一个对象(Function Return)
Person captain(){
Person player("George");
return player; // 函数返回一个对象,发生对象的拷贝
};
Person who = captain();
示例:
struct Person { string name; Person(const char* s) : name(s) { cout << "Person(const char*)" << endl; } Person(const Person& other) { cout << "Person(&)" << endl; } }; Person foo(Person p){ cout << "in foo()" << endl; return p; } Person bar(const char *s) { cout << "in bar()" << endl; return Person(s); } int main() { Person p1 = foo("Trump"); cout << "-----------------------" << endl; Person p2 = bar("Biden"); }
考虑上述代码,其输出为:
Person(const char*) in foo() Person(&) ----------------------- in bar() Person(const char*)
解释:
- 在
p1
的构造中,直接传入的是字符串,该过程并没有调用拷贝函数,而是在return p
时调用拷贝构造函数- 在
bar
函数中Person(s)
会直接在p2
的内存地址上构造,无需中间临时对象,因此不会调用拷贝构造函数
示例:
int main() { Person p1("Trump"); // 构造 Person p2("Biden"); Person p3 = p1; // 构造(由拷贝构造函数) p3 = p2; // 赋值 }
T::T(const T&)