C++_类和动态内存分配4-有关返回对象的说明
返回方式:
- 返回指向对象的引用;
- 指向对象的const引用;
- 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-有关返回对象的说明的更多相关文章
- C++_类和动态内存分配5-使用指向对象的指针
再探new和delete new为创建的每一个对象的名称字符串分配存储空间,这是在构造函数中进行的: 析构函数使用delete来释放这些内存. 字符串是一个字符数组,所以析构函数使用的是带中括号的de ...
- C++_类和动态内存分配3-构造函数中使用new的注意事项
如果在构造函数中使用new来初始化对象的指针成员时必须特别小心. 1 如果在构造函数中使用new来初始化指针成员,则应在析构函数中使用delete. 2 new和delete必须相互兼容.new对应于 ...
- C++_类和动态内存分配6-复习各种技术及队列模拟
知识点: 队列:是一种抽象的数据类型(Abstract Data Type),可以存储有序的项目序列. 新项目被添加在队尾,并可以删除队首的项目.队列有些像栈.栈是在同一端进行添加和删除.这使得栈是一 ...
- C++_类和动态内存分配1—动态内存和类
静态类成员 num_strings成员声明为静态存储类.静态类成员有一个特点:无论创建了多少对象,程序都只创建一个静态类变量副本.也就是说,类的所有对象共享一个静态成员.num_strings成员可以 ...
- C++_类和动态内存分配2-改进后的String类
添加前面介绍过的复制构造函数和赋值运算符,使类能够正确管理类对象使用的内存. 知道对象何时被创建和释放. =================================== 修订后的默认构造函数 ...
- 《C++ Primer Plus》读书笔记之十—类和动态内存分配
第12章 类和动态内存分配 1.不能在类声明中初始化静态成员变量,这是因为声明描述了如何分配内存,但并不分配内存.可以在类声明之外使用单独的语句进行初始化,这是因为静态类成员是单独存储的,而不是对象的 ...
- C++ primer plus读书笔记——第12章 类和动态内存分配
第12章 类和动态内存分配 1. 静态数据成员在类声明中声明,在包含类方法的文件中初始化.初始化时使用作用域运算符来指出静态成员所属的类.但如果静态成员是整形或枚举型const,则可以在类声明中初始化 ...
- C++——类和动态内存分配
一.动态内存和类 1.静态类成员 (1)静态类成员的特点 无论创建多少对象,程序都只创建一个静态类变量副本.也就是说,类的所有对象都共享同一个静态成员. (2)初始化静态成员变量 1)不能在类声明中初 ...
- C++拾遗(十)类与动态内存分配(2)
静态成员函数 声明时包含关键字static.注意以下两点: 1.使用静态成员函数时不能通过对象或者this指针来调用,只能使用类名+作用域解析符来调用. 2.静态成员函数只能使用静态成员. new操作 ...
随机推荐
- 170318 11:44:26 [ERROR] Can't start server: can't create PID file: No space left on device
数据库挂了.打开远程,进了系统,service mysqld stop 失败.service mysqld start等了好大一会,提示Timeout error occurred trying to ...
- 【HDU 6031]】 Innumerable Ancestors
题意 有一棵有n个结点的树,这里有m个询问,每个询问给出两个非空的结点集合A和B,有些结点可能同时在这两个集合当中.你需要从A和B中分别选择一个节点x和y(可以是同一个结点)你的目标是使LCA(x,y ...
- php 扩展开发
Linux下用C开发PHP扩展 一.首先下载PHP源码包,假设源码包目录为:/software/php-5.2.13 #> cd /software/php-5.2.13/ext 二.假设我们要 ...
- 9. Palindrome Number 回文数的判断
[抄题]: Determine whether an integer is a palindrome. An integer is a palindrome when it reads the sam ...
- Mpich编程
一.简介 通过安装MPICH构建MPI编程环境,从而进行并行程序的开发.MPICH是MPI(Message-Passing Interface)的一个应用实现,支持最新的MPI-2接口标准,是用于并行 ...
- C# 用代码返回上一页
若我们在后台.cs文件中想做到让浏览器返回上一页,我们可以在.cs代码中这样写 Page.ClientScript.RegisterStartupScript(Page.GetType(), &quo ...
- 在VS2008和VS2010中禁用Visual Assist X
此方法对于VS2008和VS2010 都适用. 在VS2008或VS2010菜单栏中选择“VassistX”选项卡,找到“Enable/Disable Visual Assist X”选项, 点击即可 ...
- 20169219 实验二 Java面向对象程序设计
实验二 Java面向对象程序设计 一.程序设计中临时变量的使用 任务: //定义一个数组 int arr[] = {1,2,3,4,5,6,7,8}; //打印原始数组的值 for(int i:arr ...
- C# 密封
到目前位置所说的都是让类如何如何进行继承啊 ,重写啊,巴不得类有十多个继承,超级多的重写. 但是,今天我们来说说不允许继承和不允许重写! 这个不允许继承是包括类和方法. 这种情况好比: 爸爸有私房钱, ...
- 解决org.hibernate.NonUniqueObjectException的问题
不知道是不是之前处理懒加载的问题对session工厂进行了处理,导致了之前没有问题的地方出现了错误. 当修改班级操作时出现了错误 前端错误信息 后台处理以及报错信息 16:37:36,034 ERRO ...