【C++注意事项】3 引用

通俗来讲,引用(reference)就是给对象另外一个名字。

1)引用必须被初始化

int &ref;  // 错误
int val=10;
int &ref2=val;  // ref2指向val(val的另一个名字)

在初始化变量时,初始值会被拷贝到新建的对象中。在定义引用时,程序把引用和它的初始值绑定(bind)在一起,而不是将初始值拷贝到引用。一旦初始化完成,引用将和它的初始值对象一直绑定在一起。因为无法令引用重新绑定到另一个对象,因此引用必须初始化。

补充:所谓对象,就是一块存储数据并具有某种类型的内存空间。

2)引用即别名。引用并非对象,它只是另外一个已经存在的对象的名字。

3)引用类型的初始值必须是一个对象。

int &ref3=10;  // 错误

4)可以把引用绑定到const对象上,就像绑定到其他对象一样,它被称为对常量的引用(reference to const)。与普通引用不同的是,对常量的引用不能被用作修改它所绑定的对象。

const int cVal= 10;
const int &cRef= cVal;  // 正确: 引用及其对应的对象都是常量
cRef=20;  // 错误: cRef是对常量的引用
int &ref2= cVal;  // 错误: 不能让一个非常量引用指向一个常量对象

5)除了下面的两种例外情况外,所有的引用类型都要和与之绑定的对象严格匹配。

double dVal=20.0;
int %ref4 = dVal;  // 错误

第一种例外情况就是在初始化常量引用时允许用任意表达式作为初始值,只要该表达式的结果能转换成引用的类型即可。【C++注意事项】1 数据类型及类型转换

尤其,允许为一个常量引用绑定非常量的对象、字面值,甚至是个一般表达式。

int i=42;
const int &r1=i;  // 允许const int&绑定到一个普通int对象上
const int &r2=42;  // 正确: r2是一个常量引用
const int &r3=r1*2;  // 正确: r3是一个常量引用
int &r4 =r1*2;  // 错误: r4是一个普通的非常量引用

下面通过一个示例来说明当一个常量引用被绑定到另一种类型上时到底发生了什么。

double dval= 3.14;
const int &ri= dval;

此处的ri引用了一个int型的数。对ri的操作应该是整数运算,但dval却是一个双精度浮点数而非整数。因此为了确保让ri绑定一个整数,编译器把上述代码变成了如下形式:

cosnt int temp= dval;
const int *ri= temp;

在这种情况下,ri其实是绑定了一个临时量(temporary)对象。所谓临时量对象就是当编译器需要一个空间来暂存表达式的求值结果时临时创建一个未命名的对象。临时量对象常被简称为临时量。

如果ri不是常量就会允许对ri赋值,这样就会改变ri所引用对象的值。而此时绑定的对象是一个临时量而非dval。既然用ri引用了dval,那么就是想通过ri修改dval的值了,否则干嘛要给ri赋值呢?那么既然不会想着把引用绑定到临时量上,C++语言便将这种行为归为非法。

6)对const的引用可能引用一个并非const的对象。常量引用仅对可参与的操作做出了限定,对于引用的对象本身是不是一个常量未作限定。因此对象也可能是一个非常量,所以允许通过其他途径改变它的值。

int i= 42;
int &r1= i;  // 引用ri绑定对象i
const int &r2= i;  // r2也绑定对象i,但是不能通过r2修改i的值
r1= 0;  // r1并非常量,i的值修改为0
r2= 0;  // 错误: r2是一个常量引用

r2绑定非常量整数i是合法的,但是不能通过r2修改i的值。但是可以通过直接赋值或者通过非常量引用来修改。

时间: 2024-10-11 04:57:18

【C++注意事项】3 引用的相关文章

Android之线程安全的单例模式,Adapter注意事项之引用传值

线程安全的单例模式单位模式一般写法如下: public static FestivalLab mInstance; private FestivalLab() { } public static FestivalLab getInstance() { if (mInstance == null) { mInstance = new FestivalLab(); } return mInstance; } 这样写不是线程安全的,因为如果两个线程都进入到这里,会实例化两次.那么如何优化呢? 线程安全

关于inline-block布局需要注意几点事项

之前在网上看到一个关于CSS基本布局的一个教学网站,内容很简洁,http://learnlayout.com/.有一小节是讲关于inline-block布局需要注意的几点事项,引用之. Inline-block : Few things that you need keep in mind You can also use inline-block for layouts. There are a few things to keep in mind: •inline-block element

MVVM

MVVM 是 Model-View-ViewModel 的简写,MVVM 模式和 MVC 模式一样,主要目的是分离视图(View)和模型(Model) 接下来给大家分享一个总结的MVVM,来吧------------------------ MVC 存在的问题 模型的代码很少 控制器的代码一不小心就越来越多 不好测试 MVVM MVVM 结构图 MVVM 概念 在 MVVM 中,view 和 view controller 正式联系在一起,我们把它们视为一个组件 view 和 view cont

转:android Support 兼容包详解

本文转自stormzhang的ANDROID SUPPORT兼容包详解 背景 来自于知乎上邀请回答的一个问题Android中AppCompat和Holo的一个问题?, 看来很多人还是对这些兼容包搞不清楚,那么干脆写篇博客吧. Support Library 我们都知道Android一些SDK比较分裂,为此google官方提供了Android Support Library package 系列的包来保证高版本sdk开发的向下兼容性, 所以你可能经常看到v4,v7,v13这些数字,首先我们就来理清

关于char[]转换成LPCWSTR的有关问题[转]

一.问题的原因:VS2010默认采用宽字符UNICODE编码方式,定义了Unicode,因此相关的字符串必须为unicode字符串,而非ascii字符串. LPCWSTR中的W是宽字符的意思,是UNICODE,就是说不是传统的char这种单字节字符,而是一个字符占两字节.编译器把LoadImage解释成了LoadImageW,说明代码中某个地方定义了UNICODE开关,编译环境成了宽字节的,要把这个定义去掉. Win32 API也分2中版本, MessageBoxA / MessageBoxW,

JAVA_面向对象2

一.JAVA类的定义 JAVA里面有class关键字定义一个类,后面加上自定义的类名即可.如这里定义的person类,使用class person定义了一个person类,然后在person这个类的类体里面定义person这个类应该具有的成员变量(即属性)和方法,如这里定义的int  id和int  age这个两个成员变量,或者叫属性,这个id表示人的身份证号码,人应该具有这个属性,age表示人的年龄,这也是人应该具有的.这样就在person这个类里面定义了两个人应该有的属性,接下来就是定义方法

Android Support兼容包详解

转载:http://stormzhang.com/android/2015/03/29/android-support-library/ 背景 来自于知乎上邀请回答的一个问题Android中AppCompat和Holo的一个问题?, 看来很多人还是对这些兼容包搞不清楚,那么干脆写篇博客吧. Support Library 我们都知道Android一些SDK比较分裂,为此google官方提供了Android Support Library package 系列的包来保证高版本sdk开发的向下兼容性

MVC 和 MVVM

MVVM MVVM 是 Model-View-ViewModel 的简写,MVVM 模式和 MVC 模式一样,主要目的是分离视图(View)和模型(Model) MVC 回顾 MVC 结构图 MVC 存在的问题 模型的代码很少 控制器的代码一不小心就越来越多 不好测试 MVVM MVVM 结构图 MVVM 概念 在 MVVM 中,view 和 view controller 正式联系在一起,我们把它们视为一个组件 view 和 view controller 都不能直接引用 model,而是引用

Android SDK中的Support兼容包详解

这篇文章主要介绍了Android SDK中的Support兼容包详解,本文详细区分了Support Library的版本区别.各种Theme的概念和使用注意事项等内容,需要的朋友可以参考下 背景 来自于知乎上邀请回答的一个问题Android中AppCompat和Holo的一个问题?, 看来很多人还是对这些兼容包搞不清楚,那么干脆写篇博客吧. Support Library 我们都知道Android一些SDK比较分裂,为此google官方提供了Android Support Library pac

Jersey框架put请求发送JSON数据

想用jersey框架发送post请求,body带json格式参数 url:http//192.168.1.211/api/test body 数据为 {"action":"test"} 实现如下: 注意事项:引用jar包一定要正确,不然调试一堆报错. 这里引用包如下: jettison-1.3.jar 这个提供JSONObject 如果用其它的可能会报各种错误. jersey-bundle-1.9.jar  这个是jersey的捆绑包,一个解决问题 javax.ws