如果类定义的数据成员中存在指针或引用,那么最好重载这两个函数。

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; //调用了私有赋值函数,编译出错

总结:如果类定义中有指针或引用变量或对象,为了避免潜在错误,必须重载拷贝构造函数和赋值函数。