StupidBeauty
Read times:6609Posted at:Thu Dec 27 00:04:42 2018 - no title specified

《C++面向对象软件设计及构建》文章翻译:4.10 赋值操作, 4.10 Assignment Operator

一个类,可定义它自己的赋值操作符。具体来说,定义的是,当某个值被赋予给该个类的某个对象时,该做出什么动作。赋值操作符必须定义成与类相关的,因为,就像复制构造函数那样,需要做一些特殊的动作,以确保,当同一个类的某个对象被赋值给另一个对象时,该对象能够做出合理的行为。默认情况下,对象的赋值操作是逐位进行的:将源对象(赋值操作符右侧的那个对象)中的内容逐个位地复制到目标对象(赋值操作符左侧的那个对象)中去。

Message 类,展示了,加入一个与类相关的赋值操作符的必要性。以下示例中,展示了两个Message 对象,其中一个,被赋值给另一个:

Message targetMsg("Hello Word");

Message sourceMsg("MacroSoft, Inc.");

...

targetMsg = sourceMsg;          // 赋值

在赋值操作符执行之前,两个对象的结构如下:


赋值操作符之前的结构

在默认的(逐位复制)赋值操作符完成之后,情况就变成了:


赋值操作符执行之后

此处有两个由默认赋值操作符引起的明显的严重问题。第一,发生了内存泄漏,因为,之前的targetMsg中的那个字符串,再也无法被访问到,而又未被返还给内存管理系统。第二,两个对象(targetMsgsourceMsg)如今都指向同一个字符串了。由于它们指向同一个字符串,所以,在其中一个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. 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. 2. 安全Address类:实现Address 类的一个安全版本。这个版本中,应当进行仔细的设计,使得,Address 对象能够被安全地复制、赋值以及销毁,并且不产生内存泄漏。

  3. 3.向Shape 类中加入一个赋值操作符。使用一个简单的主(main)程序来测试妳的代码。

  4. 4.向Location 类中加入一个赋值操作符。使用一个简单的主(main)程序来测试妳的代码。

未知美人

Your opinions
Your name:Email:Website url:Opinion content: