当前位置:嗨网首页>书籍在线阅读

20-返回const对象

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

12.4.4 返回const对象

前面的Vector::operator+()定义有一个奇异的属性,它旨在让您能够以下面这样的方式使用它:

net = force1 + force2;                            // 1: three Vector objects

然而,这种定义也允许您这样使用它:

force1 + force2 = net;                            // 2: dyslectic programming
cout << (force1 + force2 = net).magval() << endl; // 3: demented programming

这提出了三个问题。为何编写这样的语句?这些语句为何可行?这些语句有何功能?

首先,没有要编写这种语句的合理理由,但并非所有代码都是合理的。即使是程序员也会犯错。例如,为Vector类定义operator==()时,您可能错误地输入这样的代码:

if (force1 + force2 = net)

而不是:

if (force1 + force2 == net)

另外,程序员通常很有创意,这可能导致错误。

其次,这种代码之所以可行,是因为复制构造函数将创建一个临时对象来表示返回值。因此,在前面的代码中,表达式force1 + force2的结果为一个临时对象。在语句1中,该临时对象被赋给net;在语句2和语句3中,net被赋给该临时对象。

最后,使用完临时对象后,将把它丢弃。例如,对于语句2,程序计算force1和force2之和,将结果复制到临时返回对象中,再用net的内容覆盖临时对象的内容,然后将该临时对象丢弃。原来的矢量全都保持不变。语句3显示临时对象的长度,然后将其删除。

如果您担心这种行为可能引发的误用和滥用,有一种简单的解决方案:将返回类型声明为const Vector。例如,如果Vector::operator+()的返回类型被声明为const Vector,则语句1仍然合法,但语句2和语句3将是非法的。

总之,如果方法或函数要返回局部对象,则应返回对象,而不是指向对象的引用。在这种情况下,将使用复制构造函数来生成返回的对象。如果方法或函数要返回一个没有公有复制构造函数的类(如ostream类)的对象,它必须返回一个指向这种对象的引用。最后,有些方法和函数(如重载的赋值运算符)可以返回对象,也可以返回指向对象的引用,在这种情况下,应首选引用,因为其效率更高。