《C++面向对象软件设计及构建》文章翻译:4.10 赋值操作符, 4.10 Assignment Operator
一个类,可定义它自己的赋值操作符。具体来说,定义的是,当某个值被赋予给该个类的某个对象时,该做出什么动作。赋值操作符必须定义成与类相关的,因为,就像复制构造函数那样,需要做一些特殊的动作,以确保,当同一个类的某个对象被赋值给另一个对象时,该对象能够做出合理的行为。默认情况下,对象的赋值操作是逐位进行的:将源对象(赋值操作符右侧的那个对象)中的内容逐个位地复制到目标对象(赋值操作符左侧的那个对象)中去。
Message 类,展示了,加入一个与类相关的赋值操作符的必要性。以下示例中,展示了两个Message 对象,其中一个,被赋值给另一个:
Message targetMsg("Hello Word");
Message sourceMsg("MacroSoft, Inc.");
...
targetMsg = sourceMsg; // 赋值
在赋值操作符执行之前,两个对象的结构如下:
|
|
在默认的(逐位复制)赋值操作符完成之后,情况就变成了:
|
|
此处有两个由默认赋值操作符引起的明显的严重问题。第一,发生了内存泄漏,因为,之前的targetMsg中的那个字符串,再也无法被访问到,而又未被返还给内存管理系统。第二,两个对象(targetMsg和sourceMsg)如今都指向同一个字符串了。由于它们指向同一个字符串,所以,在其中一个Message 对象被销毁时,会导致另一个Message 对象指向包含未定义内容的内存。
赋值操作符应当产生如下的效果:
赋值的预期结果 |
|
在这种情形下,原来的targetMsg中的字符串("Hello World")被销毁,并且,如今targetMsg会指向原来的sourceMsg 中的字符串("MacroSoft, Inc.")的一个副本。
以下展示的Message类,包含了一个与类相关的赋值操作符:
class Message {
private:
char* message;
...
public:
...
void operator=(const Message& source);
...
};
void Message::operator=(const Message& source) {
delete message; // 销毁之前 的字符串
message = copystring(source.message); // 复制 新的字符串
}
赋值操作符的名字是"operator="。其中的"operator"部分是必须写的,它的意思是,正在为某个标准的C++操作符指定一个与类相关的新定义。具体地,要为哪个标准的C++操作符指定与类相关的定义,是由"operator"关键字之后紧接着的符号来决定的。
任务
1. 不安全的Address类:Address类,代表着一个邮政系统地址。它的具体定义中,包含两个字符串,一个表示街道地址,另一个表示城市名字和州名字,以及一个整数的邮政编码。在构造函数中必须传入所有的三个参数。例如:
Address office("123 Main St.", "Blacksburg, VA", 24061);
Address home ("456 Cozy Dr.", "Blacksburg, VA", 24061);
Address类中,有一个方法SameZip,它返回0或者1,以表示,在其上执行这个方法的地址对象,与以传值方式传入的另一个Address 对象的邮政编号是否相同。例如:
int same = office.SameZip(home);
实现Address 类的一个不安全版本,其中既没有复制构造函数也没有赋值操作符。编写一个用到了这个类的主(main)程序,以展示,使用这种不安全的类,会导致运行时错误、非预期的行为、以及/或者内存泄漏。
2. 安全的Address类:实现Address 类的一个安全版本。这个版本中,应当进行仔细的设计,使得,Address 对象能够被安全地复制、赋值以及销毁,并且不产生内存泄漏。
3.向Shape 类中加入一个赋值操作符。使用一个简单的主(main)程序来测试妳的代码。
4.向Location 类中加入一个赋值操作符。使用一个简单的主(main)程序来测试妳的代码。
未知美人
Your opinionsHxLauncher: Launch Android applications by voice commands