您的位置:首页 > 编程语言 > C语言/C++

C++中的复制、赋值、析构

2016-05-04 10:19 507 查看
一直对C++的复制(Copy)、赋值(Assign)操作比较困惑,现在看书的时候看到了,就把它顺便记下来。

一、什么时候触发


一下代码可以熟悉什么时候触发复制操作,以及什么时候触发赋值操作:

// testCopy.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include <string>

using namespace std;
class testCopy
{
public:
testCopy():a(0)
{
cout<<"enter constructor"<<endl;
};
//重载赋值操作符
testCopy& operator=(const testCopy& t)
{
cout<<"enter operator="<<endl;
a = t.a;
return *this;
}
//复制构造函数
testCopy(const testCopy& t):a(t.a)
{
cout<<"enter copy constructor"<<endl;
}
~testCopy()
{
cout<<"enter destructor"<<endl;
}
int a;
};

void f1(testCopy t2)
{
cout<<"enter f1"<<endl;
}

testCopy f2()
{
cout<<"enter f2"<<endl;
testCopy t3;//调用普通构造函数
return t3;//以类实例为非引用类型返回值时触发复制构造
}

int _tmain(int argc, _TCHAR* argv[])
{
cout<<"t1"<<endl;
testCopy t1;//调用普通构造函数
cout<<"t2"<<endl;
testCopy t2(t1);//直接以类实例为参数初始化另一个类实例时触发复制构造
cout<<"t3"<<endl;
testCopy t3;//调用普通构造函数
t3 = t1;//将类实例赋值给另一个类实例时触发赋值操作
cout<<"f1"<<endl;
f1(t1);//以类实例为非引用类型的参数传递给函数时调用复制构造
cout<<"f2"<<endl;
testCopy t4;//调用普通构造函数
t4 = f2();//将类实例赋值给另一个类实例时触发赋值操作
cout<<"end"<<endl;
return 0;
}


输出结果如下:




t1
enter constructor
t2
enter copy constructor
t3
enter constructor
enter operator=
f1
enter copy constructor
enter f1
enter destructor
f2
enter constructor
enter f2
enter constructor
enter copy constructor
enter destructor
enter operator=
enter destructor
end
enter destructor
enter destructor
enter destructor
enter destructor



二、复制、赋值、析构函数重写的必要性


上面的例子不足以说明重写复制、赋值、析构的重要性,当类中需要动态分配内存时,重要性就体现出来了:

class testCopy2
{
public:
testCopy2():buf(new char[128])
{
cout<<"enter constructor"<<endl;
};
//重载赋值操作符
testCopy2& operator=(const testCopy2& t)
{
//如果不重写赋值构造函数,那么多个类实例之间的buf指向的是同一片内存。
cout<<"enter operator="<<endl;
memcpy(buf,t.buf,128);
return *this;
}
//复制构造函数
testCopy2(const testCopy2& t):buf(new char[128])
{
cout<<"enter copy constructor"<<endl;
memcpy(buf,t.buf,128);
//如果不重写复制构造函数,那么多个类实例之间的buf指向的是同一片内存。
}
~testCopy2()
{
//如果不重写析构函数,那么buf指针内存不会被删除。
cout<<"enter destructor"<<endl;
delete buf;
}
char* buf;
};



三、一些规则


1. 如果一个类需要一个析构函数,那么它一定需要重载复制和赋值操作。

2. 如果一个类需要重载复制操作,那么它一定需要重载赋值操作,反之同成立。

3. 如果一个类需要重载复制和赋值操作,但是不一定需要重载析构操作。


四、相关下载

代码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: