C++ 拷贝构造函数、赋值运算符=的调用时机

本文通过示例代码详细解析了C++中拷贝构造函数与赋值操作符的使用场景及其工作原理,展示了不同情况下如何触发这些成员函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

至于这两种函数的用途,用于引用计数时比较有用吧,完成一些在堆上分配的数据的传递工作。[url]http://xinklabi.iteye.com/blog/653457[/url]


啥也不说了,直接上代码;注释很详细了

#include <iostream>
using namespace std;

class Class{

public:
Class(){
}
//如果用 explicit Class(const Class& c){ 来声明,则不能用Class c1=c;而只可以Class c2(c);
Class(const Class& c){
cout<<"copy construnctor called\n";
}


//=的调用者本身就是个Class类!该函数只是为了自行完成一些数据传递的任务,最后返回该调用者的引用即可
Class& operator=(const Class& c){
cout<<"= operator called\n";
return *this;
}

//函数返回时调用拷贝构造函数
static Class getClass(){
cout<<"begin getClass\n";

Class c;
cout<<"end of getClass,soon to return\n";
return c;

}

};

//类作为参数,进入函数时会调用拷贝构造函数
void classAsParam(Class c){
cout<<"begin classAsParam\n";
}

//类的引用作为参数,进入函数时不会调用拷贝构造函数
void classReferenceAsParam(Class& c){
cout<<"begin classReferenceAsParam\n";
}


void main(){
Class c;

Class c1=c;//因为是初始化,调用的是拷贝构造函数,而非=运算符
Class c2(c);//同上

cout<<"\n//////////// Test getClass without return value\n";
Class::getClass();//函数返回时调用拷贝构造函数

cout<<"\n//////////// Test getClass with new left value\n";
Class c3=Class::getClass();//函数返回时调用拷贝构造函数;由于c3在此声明,因而再调用拷贝构造函数(貌似被编译器省略了)

cout<<"\n//////////// Test getClass with exist left value\n";
c2=Class::getClass();//函数返回时调用拷贝构造函数;由于c2已经声明过,因而再调用=运算符将临时变量赋值给c2

cout<<"\n//////////// Test classAsParam\n";
classAsParam(c);//类作为参数,进入函数时会调用拷贝构造函数

cout<<"\n//////////// Test classReferenceAsParam\n";
classReferenceAsParam(c);//类的引用作为参数,进入函数时不会调用拷贝构造函数
}
### 拷贝构造函数与拷贝赋值运算符的区别使用场景 在C++中,拷贝构造函数拷贝赋值运算符是两个非常重要的概念,它们分别用于对象的初始化对象的赋值操作。以下是它们的概念、区别及使用场景的详细说明。 #### 1. 拷贝构造函数 拷贝构造函数是一种特殊的构造函数,用于通过已存在的对象来初始化新创建的对象。它的参数是一个同类型的常量引用。当需要创建一个新对象并将其初始化为另一个现有对象时,会调用拷贝构造函数。 - **定义**: 拷贝构造函数的形式通常如下: ```cpp MyClass(const MyClass& other); ``` 它接收一个同类型对象的常量引用作为参数,并利用该对象的成员变量来初始化当前对象的成员变量。 - **调用场景**: - 当用一个已有的对象去初始化一个新的对象时。 - 当函数的参数是以值传递的方式传入对象时。 - 当函数返回一个对象时(某些情况下可能会被优化掉)。 - **示例代码**: ```cpp MyClass b = a; // 调用拷贝构造函数 ``` - **注意事项**: 如果类中包含指针成员或动态分配的资源,编译器生成的默认拷贝构造函数只会进行浅拷贝,可能导致资源冲突或内存泄漏问题[^5]。 #### 2. 拷贝赋值运算符 拷贝赋值运算符是一种重载的赋值操作符,用于将一个已存在的对象赋值给另一个已存在的对象。它的作用是更新目标对象的状态以匹配源对象的状态。 - **定义**: 拷贝赋值运算符的形式通常如下: ```cpp MyClass& operator=(const MyClass& other); ``` 它返回一个指向当前对象的引用,以便支持链式赋值。 - **调用场景**: - 当一个已存在的对象被赋予另一个已存在的对象的值时。 - 在循环或其他逻辑中多次对同一个对象进行赋值时。 - **示例代码**: ```cpp MyClass c; c = a; // 调用拷贝赋值运算符 ``` - **注意事项**: 同样地,如果类中包含指针成员或动态分配的资源,需要显式实现深拷贝以避免资源冲突或内存泄漏问题[^5]。 #### 3. 区别与联系 | 特性 | 拷贝构造函数 | 拷贝赋值运算符 | |---------------------|---------------------------------------|-------------------------------------| | **主要用途** | 初始化新对象 | 更新已有对象 | | **调用时机** | 创建新对象时 | 已有对象赋值时 | | **返回值** | 无返回值 | 返回`*this`(当前对象的引用) | | **对象状态** | 目标对象尚未初始化 | 目标对象已经存在且可能已被初始化 | #### 4. 示例代码 以下是一个完整的示例,展示拷贝构造函数拷贝赋值运算符的使用: ```cpp #include <iostream> using namespace std; class MyClass { public: int x; int y; // 默认构造函数 MyClass() { x = 0; y = 0; } // 带参数的构造函数 MyClass(int a, int b) { x = a; y = b; } // 拷贝构造函数 MyClass(const MyClass& other) { x = other.x; y = other.y; cout << "拷贝构造函数调用" << endl; } // 拷贝赋值运算符 MyClass& operator=(const MyClass& other) { if (this == &other) { return *this; } x = other.x; y = other.y; cout << "拷贝赋值运算符调用" << endl; return *this; } }; int main() { MyClass a(5, 6); // 调用带参数构造函数 MyClass b = a; // 调用拷贝构造函数 MyClass c; // 调用默认构造函数 c = a; // 调用拷贝赋值运算符 return 0; } ``` #### 5. 使用场景总结 - **拷贝构造函数**适用于对象初始化阶段,例如通过已有的对象创建新对象时。 - **拷贝赋值运算符**适用于对象赋值阶段,例如将一个对象的值赋给另一个已存在的对象时。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值