在C++中,下面三种对象需要调用拷贝构造函数:
1) 一个对象以值传递的方式传入函数体;
2) 一个对象以值传递的方式从函数返回;
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;
}
参考: