返回方式

  1. 返回指向对象的引用;
  2. 指向对象的const引用;
  3. const对象;

 ===============================================

返回指向const对象的引用

假如要编写函数Max(),它返回两个Vector对象中较大的一个,其中Vector是第11章开发的一个类。

Vector force1(50, 60);

Vector force2(10,70);

Vector max;

max = Max(force1, force2);

//version 1

Vector Max(const Vector & v1, const Vector & v2)

{

if (v1.magval() > v2.magval())

return v1;

else

return v2;

}

//version 2

const Vector & Max(const Vector & v1, const Vector & v2)

{

if (v1.magval() > v2.magval())

return v1;

else

return v2;

}

返回对象将调用复制构造函数,而返回引用不会。因此第二个版本所做的工作更少,效率更高。引用指向的对象应该在调用函数执行时同时存在。

注意v1和v2被声明为const引用,所以返回类型必须为const,这样才匹配。

=============================================

返回指向非const对象的引用

Operator=()的返回值作用域连续赋值

String s1(“Good stuff”);

String s2,s3;

s3=s2=s1;

上述代码中,s2.operator=()的返回值被赋给s3。为此,返回String对象或String对象的引用都是可行的。

Operator<<()的返回值用于串接输出

String s1(“Good stuff”);

cout << s1 << “is coming!”;

operator<<(cout,s1)的返回值成员一个用于显示字符串“is coming!”的对象。返回类型必须是ostream &,而不能仅仅是ostream。如果使用返回类型ostream,将要求调用ostream类的赋值构造函数,而ostream没有公有的赋值构造函数。幸运的是,返回一个指向cout的引用不会带来任何问题,因为cout已经在调用函数的作用域内。

=================================

返回对象

如果被返回的对象是被调用函数的局部变量,则不应该按引用方式去返回它,因为在被调用函数执行完毕时,局部对象将调用析构函数。因此,当控制权回到调用函数时,引用指向的对象将不再存在。在这种情况下,应返回对象而不是引用。

通常,被重载的算术运算符属于这一类。

Vector force1();

Vector force2();

Vector net;

net = force1+force2;

返回的不是force1,也不是force2,force1和force2在这个过程中应该保持不变。因此,返回值不能是指向在调用函数中已存在的对象的引用。相反,在Vector::operator+()中计算得到的两个矢量和被存储在一个新的临时对象中,该函数也不应返回指向该临时对象的引用,而应该返回实际的Vector对象,而不是引用。

在这种情况下,存在调用复制构造函数来创建被返回的对象的开销,然而这时无法避免的。

Vector Vector::operator+(const Vector & b) const

{

Return Vector(x+b.x, y+b.y)

};

========================================

返回const对象

前面的Vector::operator+()的定义中有一个奇异的属性,

net = force1 +force2; //语句1

force1 +force2 =net; //语句2

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

如果您担心这种行为引发滥用。有个简单的解决方案,就是把返回类型声明为const Vector。那么语句2就非法了,因为返回对象无法被赋值,只能赋值给别人。

总是,如果方法或函数要返回局部对象,就必须要返回对象,而不是返回对象的引用。这种情况下将使用赋值构造函数来生成返回的对象。这样的开销是不可避免的,也是必须的。

如果方法或函数要返回一个没有公有复制构造函数的类(例如ostream类)的对象,它必须返回一个指向这种对象的引用。[ZJ2]

最后,有些方法和函数可以返回对象,也可以返回指向对象的引用,在这种情况下,应首选引用,因为其效率更高。


不能返回局部对象的引用。很危险,因为局部对象会过期,引用会失效。

C++_类和动态内存分配4-有关返回对象的说明的更多相关文章

  1. C++_类和动态内存分配5-使用指向对象的指针

    再探new和delete new为创建的每一个对象的名称字符串分配存储空间,这是在构造函数中进行的: 析构函数使用delete来释放这些内存. 字符串是一个字符数组,所以析构函数使用的是带中括号的de ...

  2. C++_类和动态内存分配3-构造函数中使用new的注意事项

    如果在构造函数中使用new来初始化对象的指针成员时必须特别小心. 1 如果在构造函数中使用new来初始化指针成员,则应在析构函数中使用delete. 2 new和delete必须相互兼容.new对应于 ...

  3. C++_类和动态内存分配6-复习各种技术及队列模拟

    知识点: 队列:是一种抽象的数据类型(Abstract Data Type),可以存储有序的项目序列. 新项目被添加在队尾,并可以删除队首的项目.队列有些像栈.栈是在同一端进行添加和删除.这使得栈是一 ...

  4. C++_类和动态内存分配1—动态内存和类

    静态类成员 num_strings成员声明为静态存储类.静态类成员有一个特点:无论创建了多少对象,程序都只创建一个静态类变量副本.也就是说,类的所有对象共享一个静态成员.num_strings成员可以 ...

  5. C++_类和动态内存分配2-改进后的String类

    添加前面介绍过的复制构造函数和赋值运算符,使类能够正确管理类对象使用的内存. 知道对象何时被创建和释放. =================================== 修订后的默认构造函数 ...

  6. 《C++ Primer Plus》读书笔记之十—类和动态内存分配

    第12章 类和动态内存分配 1.不能在类声明中初始化静态成员变量,这是因为声明描述了如何分配内存,但并不分配内存.可以在类声明之外使用单独的语句进行初始化,这是因为静态类成员是单独存储的,而不是对象的 ...

  7. C++ primer plus读书笔记——第12章 类和动态内存分配

    第12章 类和动态内存分配 1. 静态数据成员在类声明中声明,在包含类方法的文件中初始化.初始化时使用作用域运算符来指出静态成员所属的类.但如果静态成员是整形或枚举型const,则可以在类声明中初始化 ...

  8. C++——类和动态内存分配

    一.动态内存和类 1.静态类成员 (1)静态类成员的特点 无论创建多少对象,程序都只创建一个静态类变量副本.也就是说,类的所有对象都共享同一个静态成员. (2)初始化静态成员变量 1)不能在类声明中初 ...

  9. C++拾遗(十)类与动态内存分配(2)

    静态成员函数 声明时包含关键字static.注意以下两点: 1.使用静态成员函数时不能通过对象或者this指针来调用,只能使用类名+作用域解析符来调用. 2.静态成员函数只能使用静态成员. new操作 ...

随机推荐

  1. 关于ptrdiff_t

    整除.opencv中的内存一般是通过malloc分配,不能保证都是都能被16整除,此时需要截断,但是剩下的内存要如何维护? CV2.0的这样维护的:在 malloc 是多申请一个指针的空间,这个指针指 ...

  2. python 将字符串转化为可执行代码

    场景: 在一个遍历的的程序中,有一步需要调用函数,调用的方式是根据输入参数,从3个可供被调用的函数中,选择其中一个.所以写了一个dict={1:"function_a_name", ...

  3. Luogu 4755 Beautiful Pair

    分治 + 主席树. 设$solve(l, r)$表示当前处理到$[l, r]$区间的情况,我们可以找到$[l, r]$中最大的一个数的位置$mid$,然后扫一半区间计算一下这个区间的答案. 注意,这时 ...

  4. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(4):JDK动态代理+拦截器

    一.拦截器的理解 学习拦截器之前需要对动态代理和反射有一定的基础. 官方说法:         java里的拦截器是动态拦截Action调用的对象.它提供了一种机制可以使开发者可以定义在一个actio ...

  5. 使用IneliJ IDEA 2016将Java Web项目导出为War包

    本文记录使用IDEA导出war包的过程以及碰到问题的解决办法 虽说现在改用IDEA进行开发了,但还是用eclipse打war包 -.囧 这样下去不是办法... 于是今天就试着使用IDEA进行打包. 项 ...

  6. POJ1062 昂贵的聘礼(带限制的spfa)

    Description 年轻的探险家来到了一个印第安部落里.在那里他和酋长的女儿相爱了,于是便向酋长去求亲.酋长要他用10000个金币作为聘礼才答应把女儿嫁给他.探险家拿不出这么多金币,便请求酋长降低 ...

  7. 软工作业WordCount

    github项目传送门:https://github.com/zzh010/My-wc 一.WC 项目要求 wc.exe 是一个常见的工具,它能统计文本文件的字符数.单词数和行数.这个项目要求写一个命 ...

  8. Java变量的修饰符

    1.public public的类.类属变量及方法,包内及包外的任何类均可以访问: 2.protect protected的类.类属变量及方法,包内的任何类,及包外的那些继承了此类的子类才能访问: 3 ...

  9. wp8 与wp7.5图标规格说明

    wp8 小图标 159*159 中图标 336*336 大图标 691*336 wp7.5 173*173

  10. xp 专业版组策略只有系统组件

    想要不显示任务栏的提示消息,需要在组策略里面设置,(在"开始→运行"中输入"GPEDIT.MSC"打开组策略,然后依次选择"用户配置→管理模板→任务栏 ...