类String的赋值函数比结构函数巨大得多,分四步实现:
(1)第一步,查抄自赋值。你大概会认为添枝加叶,莫非有人会愚蠢到写出 a = a 这样的自赋值语句!简直不会。可是间接的自赋值仍有大概呈现,譬喻
// 内容自赋值
b = a;
…
c = b;
…
a = c;
// 地点自赋值
b = &a;
…
a = *b;
也许有人会说:“纵然呈现自赋值,我也可以不答理,大不了化点时间让工具复制本身罢了,横竖不会堕落!”
他真的说错了。看看第二步的delete,自杀后还能复制本身吗?所以,假如发明自赋值,应该顿时终止函数。留意不要将查抄自赋值的if语句
if(this == &other)
错写成为
if( *this == other)
(2)第二步,用delete释放原有的内存资源。假如此刻不释放,今后就没时机了,将造成内存泄露。
(3)第三步,分派新的内存资源,并复制字符串。留意函数strlen返回的是有效字符串长度,不包括竣事符‘\0’。函数strcpy则连‘\0’一起复制。
(4)第四步,返回本工具的引用,目标是为了实现象 a = b = c 这样的链式表达。留意不要将 return *this 错写成 return this 。那么可否写成return other 呢?结果不是一样吗?
不行以!因为我们不知道参数other的生命期。有大概other是个姑且工具,在赋值竣事后它顿时消失,那么return other返回的将是垃圾。
9.7 偷懒的步伐处理惩罚拷贝结构函数与赋值函数
假如我们实在不想编写拷贝结构函数和赋值函数,又不答允别人利用编译器生成的缺省函数,怎么办?
偷懒的步伐是:只需将拷贝结构函数和赋值函数声明为私有函数,不消编写代码。
譬喻:
class A
{ …
private:
A(const A &a); // 私有的拷贝结构函数
A & operate =(const A &a); // 私有的赋值函数
};
假如有人试图编写如下措施:
A b(a); // 挪用了私有的拷贝结构函数
b = a; // 挪用了私有的赋值函数
编译器将指堕落误,因为外界不行以操纵A的私有函数。
9.8 如安在派生类中实现类的根基函数
基类的结构函数、析构函数、赋值函数都不能被派生类担任。假如类之间存在担任干系,在编写上述根基函数时应留意以下事项:
u 派生类的结构函数应在其初始化内外挪用基类的结构函数。
u 基类与派生类的析构函数应该为虚(即加virtual)