如果类定义的数据成员中存在指针或引用,那么最好重载这两个函数。
1. 定义
拷贝构造函数的定义格式:构造函数名(const 源类名& 引用对象形参名){}
赋值函数定义格式:源类名 & operate=(const 源类名& 引用对象形参名)。
(注:声明为const类型是为了避免对源对象的误操作)。
拷贝构造函数与赋值函数体的内容差不多:如
class Demo
{
int nLen;
char* p;
public:
Demo(const char* s){nLen=strlen(s);p=newchar[nLen+1];strcpy(p,s);}
Demo(const Demo& st){ nLen=strlen(st.p);p=newchar[nLen+1];strcpy(p,st.p);}
Demo(){p=new char[8];}
~Demo(){delete p;}
Demo& operate=(const Demo& st)
{
Demo d;
delete d.p;
d.nLen=strlen(st.p);
d.p=newchar[nLen+1];
strcpy(d.p,st.p);
return d;
}
}
2. 区别:
拷贝构造函数时在对象创建时调用,而赋值函数只能被已经存在的对象调用。如:
String a(“hello”)
String b(“world”);
String c=a; //调用拷贝构造函数(这种语句风格较差,应该写成String c(a))
String d;
d =b; //调用赋值函数
3. 如果不想编写拷贝构造函数和赋值函数,又不允许别人使用编译器生成的缺省函数,最简单的办法是将拷贝构造函数和赋值函数声明为私有函数,不用编写代码。如:
class A
{
private:
A(const A& a); //私有拷贝构造函数
A & operate=(const A& a); //私有赋值函数
}
如果程序这样写就会出错:
A a;
A b(a); //调用了私有拷贝构造函数,编译出错
A b;
b=a; //调用了私有赋值函数,编译出错
总结:如果类定义中有指针或引用变量或对象,为了避免潜在错误,必须重载拷贝构造函数和赋值函数。