Chinaunix首页 | 论坛 | 博客
  • 博客访问: 205620
  • 博文数量: 264
  • 博客积分: 6010
  • 博客等级: 准将
  • 技术积分: 2740
  • 用 户 组: 普通用户
  • 注册时间: 2009-06-03 13:25
文章分类

全部博文(264)

文章存档

2011年(1)

2009年(263)

我的朋友

分类: C/C++

2009-06-04 12:40:01

const 引用是指向const 对象的引用8 x( {( n+ r4 R% f
const int ival=1024;  F. K  m/ t9 b* d: Q+ V$ t
const int &refVal=ival; //ok,both reference and object are const
9 N# k7 B3 K5 q7 c$ ^, d9 u2 jint  &ref2=ival;        //error! non const reference to a const object
' \4 P* u+ ~: m  ?+ }3 O可以读取但不能修改refVal,因此,任何对refVal的赋值都是不合法的。这个限制有其意义:不能直接对ival同值,因此不能通过使用refVal来修改ival。( j* M( Q  S6 ^6 K6 [. C+ p6 G
同理,用ival初始化ref2也是不合法的:ref2是普通的非const引用,因此可以用来修改ref2 指向的对象的值。能过ref2对ival赋值会导致修改const对象的值。为阻止这样的修改,需要规定将普通的引用绑定到const对象是不合法的。+ V+ I% b5 i: |' Y$ r) o
const 引用可以初始化为不同类型的对象或者初始化为右值,如字面值常量:3 j4 C  V% m& @/ x: i
int i=42;
8 g0 @/ s$ n0 i1 L$ ^9 [) Q// legal for const reference ONLY!8 a) s7 L1 \' w' o
const int &r=42;
- t8 b& s3 Z% Y# ^( r! `const int &r2=r+i;
' M( O$ G. J- d, |$ idouble dval=3.14;" a* o% h* M8 L! U
const int &r3=dval;3 k- m5 u+ e% K1 j* y: c0 w9 k
编译器展开:
; d9 H$ y% D, [9 Eint temp=dval;
* |: b/ P: u2 Q7 B" C' I" ~/ fconst int &ri=temp;6 b, y. N! x5 U
非const引用只能绑定到与该引用同类型的对象。
! j- i7 [3 Y7 b# L0 \const引用则可以绑定到不同但相关的类型的对象或绑定到右值。( J2 k7 X' n- j/ a+ z$ D
在C++中真正的临时对象是看不见的,它们不出现在你的源代码中。建立一个没有命名的非堆(non-heap)对象会产生临时对象。这种未命名的对象通常 在两种条件下产生:为了使函数成功调用而进行隐式类型转换和函数返回对象时。理解如何和为什么建立这些临时对象是很重要的,因为构造和释放它们的开销对于 程序的性能来说有着不可忽视的影响。
+ `# ?- p2 a$ s. n首先考虑为使函数成功调用而建立临时对象这种情况。当传送给函数的对象类型与参数类型不匹配时会产生这种情况。/ w+ @2 ^0 q( k! C/ Z# `
在字符计数的例子里,能够成功传递char数组到countChar中,但是在这里试图用char数组调用upeercasify函数,则不会成功:。考虑一下这个函数:- s* c9 }" F7 N* `. h( u8 o; h
void uppercasify(string& str);" \* Q" }9 @. X! ~" s' n
char subtleBookPlug[] = "Effective C++";
! \" L$ p5 |  x9 @4 {uppercasify(subtleBookPlug); // 错误!
! k% x; M+ s) R4 ~没有为使调用成功而建立临时对象,为什么呢?0 m7 q' j, \: E$ W5 j$ F% u( {
假设建立一个临时对象,那么临时对象将被传递到upeercasify中,其会修改这个临时对象,把它的字符改成大写。但是对 subtleBookPlug函数调用的真正参数没有任何影响;仅仅改变了临时从subtleBookPlug生成的string对象。无疑这不是程序员 所希望的。程序员传递subtleBookPlug参数到uppercasify函数中,期望修改subtleBookPlug的值。当程序员期望修改非 临时对象时,对非常量引用(references-to-non-const)进行的隐式类型转换却修改临时对象。这就是为什么C++语言禁止为非常量引 用(reference-to-non-const)产生临时对象。这样非常量引用(reference-to-non-const)参数就不会遇到这种 问题。
( s) P+ a2 @& L; M: }; C: O+ U: e  E' x" D! W
把一个const对象的地址赋给一个普通的,非const对象的指针也会导致编译时错误:( H% y% \( W6 x9 }' C4 y3 L, ?
const double pi=3.14;
* A2 E" J8 e' E  c8 X1 k' a) ]% Idouble *ptr=π   //error:ptr is a plain pointer
9 B5 a& E+ H* W& ]+ Aconst double *cptr=π  //ok:cptr is a pointer to const
& {$ F+ e7 B0 v5 g# w不能使用void*指针保存const 对象的地址,而必须用const void*类型的指针保存。
, M% Q! ~) {8 C5 s  lconst int universe=42;, N$ W! ?5 [6 F0 u
const void *cpv=&universe; //ok;
- u" A2 C0 |5 Dvoid *pv=&universe;      //error:universe is const5 i  V* {: z9 p' S8 o3 O
允许把非const 对象的地址赋给指向const 对象的指针:
$ C2 ~& m- Q% m+ `0 ndouble dval=3.14;
4 ~' \6 D/ c: p& g0 ^cptr=&dval;( E0 W# w& P. D! X( {# N
typedef string *pstring;9 V8 i2 X9 ?8 w. e! n* ]
const pstring cstr;7 b# ^  w7 `6 U" ~. X; {
//cstr is a const pointer to string4 m7 n9 @) C- Y% c+ [3 Y
string *const cstr  ; // equivalent to const pstring cstr; 4 B" e' E$ W. o3 N- L, f( l+ |

1 n  K# w( e5 H( E3 ?: ZSales_item成员函数形参表后面的const后面所起的作用:const 改变了隐含的this 形参的类型。在调用
( Z1 q% A3 U* O0 A: F) K- a% P# f. ttotal.same_isbn(trans)时,隐含的this形参将是一个指向total对象的const Sales_item *类型的指针。
$ a. \  g: K; n5 W% P3 n由于this 是指向const对象的指针,const 成员函数不能修改调用该函数的对象。
: |; m- x( z' U" V+ Mconst 对象,指向const对象的指针或引用只能用于调用其const成员函数,如果尝试用它们调用非+ }  j3 u  j7 g* Y# S' G8 s
const 成员函数,则是错误的。
阅读(217) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~