C++ const引用详解

(1) 在实际的程序中,引用主要被用做函数的形式参数--通常将类对象传递给一个函数.引用必须初始化.但是用对象的地址初始化引用是错误的,我们可以定义一个指针引用。

int ival = 1092;

int &re = ival;//ok

int &re2 = &ival;//错误

int *pi = &ival;

int *&pi2 = pi;//ok

(2) 一旦引用已经定义,它就不能再指向其他的对象.这就是为什么它要被初始化的原因。

(3) const引用可以用不同类型的对象初始化(只要能从一种类型转换到另一种类型即可),也可以是不可寻址的值,如文字常量。例如

double dval = 3.14159;

//下3行仅对const引用才是合法的

constint &ir = 1024;

constint &ir2 = dval;

constdouble &dr = dval + 1.0;

       上面,同样的初始化对于非const引用是不合法的,将导致编译错误。原因有些微妙,需要适当做些解释。

引用在内部存放的是一个对象的地址,它是该对象的别名。对于不可寻址的值,如文字常量,以及不同类型的对象,编译器为了实现引用,必须生成一个临时对象,引用实际上指向该对象,但用户不能访问它。

例如:

double dval = 23;

constint &ri = dval;

编译器将其转换为:

int tmp = dval;// double -> int

constint &ri = tmp;


同理:上面代码

double dval = 3.14159;

//下3行仅对const引用才是合法的

constint &ir = 1024;

constint &ir2 = dval;

constdouble &dr = dval + 1.0;


内部转化为:

double dval = 3.14159;

//不可寻址,文字常量

int tmp1 = 1024;

constint &ir = tmp1;

//不同类型

int tmp2 = dval;//double -> int

constint &ir2 = tmp2;

//另一种情况,不可寻址

double tmp3 = dval + 1.0;

constdouble &dr = tmp3;


(4) 不允许非const引用指向需要临时对象的对象或值,即,编译器产生临时变量的时候引用必须为const!!!!切记!!

int iv = 100;

int *&pir = &iv;//错误,非const引用对需要临时对象的引用

int *const &pir = &iv;//ok

constint ival = 1024;

int *&pi_ref = &ival;//错误,非const引用是非法的

constint *&pi_ref = &ival;//错误,需要临时变量,且引用的是指针,而pi_ref是一个非常量指针

constint *const &pi_ref = &ival;//正确

//补充

constint *p = &ival;

constint *&pi_ref = p;//正确

(5)********对于const int *const & pi_ref = &iva;具体的分析如下:*********

1.不允许非const引用指向需要临时对象的对象或值

int a = 2;

int &ref1 = a;// OK.有过渡变量。

constint &ref2 = 2;// OK.编译器产生临时变量,需要const引用

2.地址值是不可寻址的值

int *const &ref3 = &a;// OK;

3.于是,用const对象的地址来初始化一个指向指针的引用

constint b = 23;

constint *p = &b;

constint *& ref4 = p;

constint *const & ref5 = &b; //OK

const引用的语义到底是什么?

最后,我们可能仍然不明白const引用的这个const的语义是什么

const引用表示,试图通过此引用去(间接)改变其引用的对象的值时,编译器会报错!

这并意味着,此引用所引用的对象也因此变成const类型了。我们仍然可以改变其指向对象的值,只是不通过引用

下面是一个简单的例子:

#include <iostream>

usingnamespace std;

int main()

{

   int val = 1024;

   constint &ir = val;

   val++;

   //ir++;

   cout << val << " " << ir << endl;

   return 0;

}

 

其中第10行,如果我们通过ir来改变val的值,编译时会出错。但是我们仍然可以通过val直接改变其值(9)

总结:const引用只是表明,保证不会通过此引用间接的改变被引用的对象!

另外,const既可以放到类型前又可以放到类型后面,放类型后比较容易理解:

string const *t1;

const string *t1;

typedef string* pstring;string s;

const pstring cstr1 = &s;就出错了

但是放在类型后面不会出错:

pstring const cstr2 = &s;

 

转载:http://blog.csdn.net/k2eats/article/details/2541790

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值