从零开始学C++之从C到C++(二):引用、内联函数inline、四种类型转换运算符
一、引用
(1)、引用是给一个变量起别名
定义引用的一般格式:类型 &引用名 = 变量名;
例如:int a=1; int &b=a;// b是a的别名,因此a和b是同一个单元
注意:定义引用时一定要初始化,指明该引用变量是谁的别名
在实际应用中,引用一般用作参数传递与返回值
引用不是变量,引用仅仅只是变量的别名,引用没有自己独立的空间,引用要与它所引用的变量共享空间,对引用所做的改变实际上是对它所引用的变量的改变,引用在定义的时候要进行初始化,引用一经初始化,不能重新指向其他变量。
(2)const 引用
const引用是指向const对象的引用
const int ival = 1024;
const int& refVal = ival;//ok:both reference and object are const
int &ref2 = ival;//error:nonconst reference to a const object
(3)、按引用传递
引用传递方式是在函数定义时在形参前面加上引用运算符"&"
例如:swap(int &a,int &b);
按值传递方式容易理解,但形参值的改变不能对实参产生影响
地址传递方式通过形参的改变使相应的实参改变,但程序容易产生错误且难以阅读
引用作为参数对形参的任何操作都能改变相应的实参的数据,又使函数调用显得方便、自然
|
1 |
#include <iostream>
using namespace std; void swap( int &x, int &y); int main( void) { int a, b; a = ; b = ; swap(a, b); cout << "a=" << a << "b=" << b << endl; return ; } void swap( int &x, int &y) { int temp; temp = x; x = y; y = temp; } |
注意:引用作参数时,函数的实参与形参在内存中共用存储单元,因此形参的变化会使实参同时变化。
(4)、引用作为返回值
引用的另一个作用是用于返回引用的函数
函数返回引用的一个主要目的是可以将函数放在赋值运算符的左边。
注意:不能返回对局部变量的引用,具体可以参见我的这篇文章,文章里面还比较了引用与指针的关系。
(5)、引用与指针区别
引用访问一个变量是直接访问,而指针是间接访问。
引用是一个变量的别名,本身不单独分配自己的内存空间,而指针有自己的内存空间。
引用一经初始化不能再引用其它变量,而指针可以。
c++建议尽可能使用引用,不得已时使用指针。
二、内联函数
(1)、内联函数
当程序执行函数调用时,系统要建立栈空间,保护现场,传递参数以及控制程序执行的转移等等,这些工作需要系统时间和空间的开销。有些情况下,函数本身功能简单,代码很短,但使用频率却很高,程序频繁调用该函数所花费的时间却很多,从而使得程序执行效率降低。
为了提高效率,一个解决办法就是不使用函数,直接将函数的代码嵌入到程序中,可以使用带参数的宏定义实现,但是这种方法也有缺点,程序可读性往往没有使用函数的好,如果缺少了一些括号还可能出现歧义。
为了协调好效率和可读性之间的矛盾,C++提供了另一种方法,即定义内联函数,方法是在定义函数时用修饰词inline。inline关键字告诉编译器,这个函数的调用要尽可能快,可以当普通的函数调用实现,也可以用宏展开的办法实现。在C99也引入了inline 关键字。
(2)、内联函数和带参数的宏的区别
inline int max(int a, int b)
{
return a > b ? a : b;
}
#define MAX(a, b) ((a) > (b) ? (a) : (b))
内联函数调用时,要求实参和形参的类型一致,另外内联函数会先对实参表达式进行求值,然后传递给形参;如果实参表达式有Side Effect,那么这些SideEffect只发生一次。例如MAX(++a, ++b),如果MAX是个真正的函数,a和b只增加一次。而宏调用时只用实参简单地替换形参;如果MAX是上面那样的宏定义,则要展开成k = ((++a)>(++b)?(++a):(++b)),a和b 增加的次数就难说了。
内联函数是在编译的时候、在调用的地方将代码展开的,而参数宏则是在预处理时进行替换的,故生成的目标文件比较大。
在C++中建议采用inline函数来替换带参数的宏。
三、四种类型转换
参考我的这篇文章。
参考:
C++ primer 第四版
Effective C++ 3rd
C++编程规范
从零开始学C++之从C到C++(二):引用、内联函数inline、四种类型转换运算符的更多相关文章
- 从零开始学 Java - Spring 集成 ActiveMQ 配置(二)
从上一篇开始说起 上一篇从零开始学 Java - Spring 集成 ActiveMQ 配置(一)文章中讲了我关于消息队列的思考过程,现在这一篇会讲到 ActivMQ 与 Spring 框架的整合配置 ...
- 从零开始学C++之IO流类库(二):文件流(fstream, ifstream, ofstream)的打开关闭、流状态
一.文件流 ofstream,由ostream派生而来,用于写文件 ifstream,由istream派生而来, 用于读文件 fstream,由iostream派生而来,用于读写文件 二.打开文件 说 ...
- 从零开始学C++之对象的使用(二):四种对象生存期和作用域、static 用法总结
一.四种对象生存期和作用域 栈对象 隐含调用构造函数(程序中没有显式调用) 堆对象 隐含调用构造函数(程序中没有显式调用),要显式释放 全局对象.静态全局对象 全局对象的构造先于main函数 已初始化 ...
- 从零开始学C++之构造函数与析构函数(二):初始化列表(const和引用成员)、拷贝构造函数
一.构造函数初始化列表 推荐在构造函数初始化列表中进行初始化 构造函数的执行分为两个阶段 初始化段 普通计算段 (一).对象成员及其初始化 C++ Code 1 2 3 4 5 6 7 8 9 1 ...
- 从零开始学spring源码之xml解析(二):默认标签和自定义标签解析
默认标签: 上一篇说到spring的默认标签和自定义标签,发现这里面东西还蛮多的.决定还是拆开来写.今天就来好好聊聊这两块是怎么玩的,首先我们先看看默认标签: private void parseDe ...
- 从零开始学 Java - Spring 集成 ActiveMQ 配置(一)
你家小区下面有没有快递柜 近两年来,我们收取快递的方式好像变了,变得我们其实并不需要见到快递小哥也能拿到自己的快递了.对,我说的就是类似快递柜.菜鸟驿站这类的代收点的出现,把我们原来快递小哥必须拿着快 ...
- 从零开始学 Java - Spring 集成 Memcached 缓存配置(一)
硬盘和内存的作用是什么 硬盘的作用毫无疑问我们大家都清楚,不就是用来存储数据文件的么?如照片.视频.各种文档或等等,肯定也有你喜欢的某位岛国老师的动作片,这个时候无论我们电脑是否关机重启它们永远在那里 ...
- 从零开始学 Java - 我放弃了 .NET ?
这不是一篇引起战争的文章 毫无疑问,我之前是一名在微软温暖怀抱下干了近三年的 .NET 开发者,为什么要牛(sha)X一样去搞 Java 呢?因为我喜欢 iOS 阿!哈哈,开个玩笑.其实,开始学 Ja ...
- 从零开始学 Web 系列教程
大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新…… github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:http:/ ...
随机推荐
- 新书:《Liferay Portal 6.1最佳实践门户网站建设》
新书:<Liferay Portal 6.1最佳实践门户网站建设> <Liferay Portal 6.1门户站点建设最佳实践>是国内第一本全面介绍Liferay Port ...
- CloudStack全局配置參数
參数 描写叙述 类型 默认值 account.cleanup.interval 清除用户账户所须要等待的时间(秒) 整数 86400 agent.lb.enabled If agent load ba ...
- PHP - 接口&抽象类
什么时候使用抽象类什么时候使用接口? .如果要创建一个模型,这个模型将由一些紧密相关的对象采用,就可以使用抽象类.如果要创建将由一些不相关对象采用的功能,就使用接口. .如果必须从多个来源继承行为,就 ...
- WCF技术剖析之六:为什么在基于ASP.NET应用寄宿(Hosting)下配置的BaseAddress无效
原文:WCF技术剖析之六:为什么在基于ASP.NET应用寄宿(Hosting)下配置的BaseAddress无效 本篇文章来源于几天前一个朋友向我咨询的问题.问题是这样的,他说他采用ASP.NET应用 ...
- 谈论Java原子变量和同步的效率 -- 颠覆你的生活
我们认为,由于思维定式原子变量总是比同步运行的速度更快,我想是这样也已经,直到实现了ID在第一次测试过程生成器不具有在这样一个迷迷糊糊的东西. 测试代码: import java.util.Array ...
- [置顶] Android下实现自动关机的方法总结
最近在网上看了一些Android下实现自动关机的方法,有的不行,有的只适用一些机型,有的适用于大部分机型,笔者在此总结一下 法一: Intent newIntent = new Intent(Inte ...
- 实现长按删除QListWidget的Item
原地址:http://blog.sina.com.cn/s/blog_5c70dfc80100r99u.html 要想长按删除QListWidget的Item,必须重写鼠标事件,所以需要继承QList ...
- Kendo UI开发教程(20): Kendo MVVM 数据绑定(九) Text
Text绑定可以使用ViewModel来设置DOM元素的文本属性,如果需要设置input,textarea,或select的显示,需要使用value属性. 1 <span data-bind=& ...
- Swift - UIView的常用属性和常用方法总结
1,UIView常用的一些属性如下: frame:相对父视图的坐标和大小(x,y,w,h) bounds:相对自身的坐标和大小,所以bounds的x和y永远为0(0,0,w,h) center:相对父 ...
- jquery用div模拟一个下拉列表框
原文 jquery用div模拟一个下拉列表框 今天分享一个用我自己用jquery写的,用div模拟下拉列表select,这个效果网上有很多,但是写一个有自己思路的代码效果,更有成就感,先看截图: 自我 ...