C++在定义类的时候,如果我们没有手动定义拷贝构造函数,系统会有一个默认拷贝构造函数,此拷贝构造函数为浅拷贝。那什么是拷贝构造函数呢?它的形式如下:
A(A &a){}
其中A为类名。我们经常见到类似
A b=new A(a);
形式的语句,拷贝构造函数就是用在这里来为新创建的对象b用已经存在的对象a初始化的。一般情况下使用默认的拷贝构造函数即可,然而当类中有指针变量时,需要手动定义深拷贝构造函数以保证使用中因a对象的指针变量空间释放造成b对象中该指针变量的继续使用。以下为一个深拷贝例子:
// A.hpp
#ifndef A_hpp
#define A_hpp
#include "iostream"
class A {
private:
int num;
char* name;
public:
A(A &a);//注释
A(int a,char* c);
void setnum(int n);
int getnum();
void setname(char* s);
char* getname();
};
#endif /* A_hpp */
// A.cpp
#include "A.hpp"
using namespace std;
int A::getnum()
{
return num;
}
void A::setnum(int n)
{
num = n;
}
void A::setname(char* s)
{
for(int i=0;i<num;i++)
name[i]=s[i];
}
char* A::getname()
{
return name;
}
A::A(A &a){//注释
num = a.num;//.getnum();//注释
name = new char[num];//注释
strcpy(name, a.getname());//注释
}//注释
A::A(int a,char* c)
{
num = a;
name = c;
}
// main.cpp
#include <iostream>
#include "A.hpp"
using namespace std;
int main(int argc, const char * argv[]) {
char* fan=new char[3];
fan[0]='f';
fan[1]='a';
fan[2]='n';
A a1(3,fan);
A a2(a1);
a1.setnum(9);
char* liu=new char[3];
liu[0]='l';
liu[1]='i';
liu[2]='u';
a1.setname(liu);
cout<<a1.getname()<<endl;
cout<<a2.getname()<<endl;
return 0;
}
程序中标识注释的语句即为自定义的深拷贝构造函数,采用这一方式时,a1的赋值将不会影响a2的输出,将其注释掉则a1的赋值将影响到a2的输出,即采用默认拷贝构造函数。