C++中的拷贝构造函数

在C++中,下面三种对象需要调用拷贝构造函数:
1) 一个对象以值传递的方式传入函数体;
2) 一个对象以值传递的方式从函数返回

3) 一个对象需要通过另外一个对象进行初始化

注意:

1.如果不主动编写拷贝构造函数和赋值函数,编译器将以“位拷贝”的方式自动生成缺省的函数。

2.类中有指针类型的数据成员事就要调用自己写的拷贝构造函数 避免指针所指向的内存被释放两次(即:当含有指针时,如果调用默认的拷贝拷贝构造函数(赋值运算符),这个时候进行的浅拷贝(赋值),或者是影子拷贝,会使2个指针指向同一个内存区域,析构的时候就会出现同一个内存资源被释放2次的错误。对象存在资源但复制过程并未复制资源的情况视为浅拷贝。

3.如果对象有动态分配的内存,一般来说要么自定义拷贝构造函数进行深拷贝,要么就禁用拷贝构造函数

3.如果自定义了复制操作符:=,那么必须自定义拷贝构造函数


当我们没有自定义拷贝函数的时候,有错误。

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

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

using namespace std;
//#include <string>

class String
{
	int nLen;
	char *cArray;
public:
	String() {nLen =0; cArray=NULL;}
	~String() 
	{
		cout << "~String()" <<endl;
		delete[] 
		cArray;
		nLen=0; 
	}
	//构造函数	
	String(const char *str)
	{
		int len = strlen(str) + 1;
		cArray = new char[len];
		strcpy(cArray, str); //将str拷贝给cArray,返回cArray
		nLen = len;
	}

	void operator=(const char*str)
	{
		if(nLen)
			delete []cArray;
		int len = strlen(str) + 1;
		cArray = new char[len];
		strcpy(cArray,str);
		nLen = len;
	}

	char *GetBuffer() const { return cArray;}

	//*********自己写的拷贝构造函数*****
	/*String(const String &s)
	{
		cout << "拷贝构造函数" << endl;
		char *tmp;
		tmp = new char[s.nLen];
		strcpy(tmp,s.GetBuffer());
		cArray = new char[s.nLen];
		strcpy(cArray,tmp);
		delete tmp;
	}*/

	String operator=(String p) //第一次是,执行str=s时,将实参s拷贝给String operator=(String p)函数的形参p.
	{
		if(nLen)
			delete []cArray;
		strcpy(p.cArray,p.GetBuffer());
		int len = strlen(p.GetBuffer()) +1;
		cArray = new char[len];
		nLen = len;
		strcpy(cArray, p.GetBuffer());
		return *this;//第二次调用拷贝构造函数,返回时
	}	

};

int _tmain(int argc, _TCHAR* argv[])
{
	String str("Hello,World!");
	char *p = str.GetBuffer();
	cout << p << endl;

	str = "Hello";
	p = str.GetBuffer();
	cout << p << endl;
	/***********/
	String s = "Hello";
	str = s;     //开始出错了
	p=str.GetBuffer();
	cout << p << endl;

	return 0;
}


在自定义拷贝函数后

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

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

using namespace std;
//#include <string>

class String
{
	int nLen;
	char *cArray;
public:
	String() {nLen =0; cArray=NULL;}
	~String() 
	{
		cout << "~String()" <<endl;
		delete[] 
		cArray;
		nLen=0; 
	}
	//构造函数	
	String(const char *str)
	{
		int len = strlen(str) + 1;
		cArray = new char[len];
		strcpy(cArray, str); //将str拷贝给cArray,返回cArray
		nLen = len;
	}

	void operator=(const char*str)
	{
		if(nLen)
			delete []cArray;
		int len = strlen(str) + 1;
		cArray = new char[len];
		strcpy(cArray,str);
		nLen = len;
	}

	char *GetBuffer() const { return cArray;}

	//*********自己写的拷贝构造函数*****
	String(const String &s)
	{
		cout << "拷贝构造函数" << endl;
		char *tmp;
		tmp = new char[s.nLen];
		strcpy(tmp,s.GetBuffer());
		cArray = new char[s.nLen];
		strcpy(cArray,tmp);
		delete tmp;
	}

	String operator=(String p) //第一次是,执行str=s时,将实参s拷贝给String operator=(String p)函数的形参p.
	{
		if(nLen)
			delete []cArray;
		strcpy(p.cArray,p.GetBuffer());
		int len = strlen(p.GetBuffer()) +1;
		cArray = new char[len];
		nLen = len;
		strcpy(cArray, p.GetBuffer());
		return *this;//第二次调用拷贝构造函数,返回时
	}	

};

int _tmain(int argc, _TCHAR* argv[])
{
	String str("Hello,World!");
	char *p = str.GetBuffer();
	cout << p << endl;

	str = "Hello";
	p = str.GetBuffer();
	cout << p << endl;
	/***********/
	String s = "Hello";
	str = s;     //调用拷贝构造函数
	p=str.GetBuffer();
	cout << p << endl;

	return 0;
}


参考:

http://blog.sina.com.cn/s/blog_6adee4450100l2go.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值