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的输出,即采用默认拷贝构造函数。