3、函数中使用CONST
/ S3 Z# ^- y$ v& e7 _ (1)const修饰函数参数
" r2 V) f7 t' M4 m( p a.传递过来的参数在函数内不可以改变(无意义,因为Var本身就是形参)
" M/ |3 z" c$ {3 y' M void function(const int Var);1 m* Z+ f2 n: t0 C1 P# X
b.参数指针所指内容为常量不可变
% s0 v' R* a$ Q$ ?3 J- S1 j1 C void function(const char* Var);* G" \4 P2 D( I7 b8 x6 H
c.参数指针本身为常量不可变(也无意义,因为char* Var也是形参)
0 i8 ]) `! ]* h h8 f/ K void function(char* const Var);! X2 Z7 K; u" e& M4 q
d.参数为引用,为了增加效率同时防止修改。修饰引用参数时:
( T( ]' u1 I4 r6 s# e0 ?( I8 b void function(const Class& Var); //引用参数在函数内不可以改变9 y5 `, g2 {; [+ j! C9 Q
void function(const TYPE& Var); //引用参数在函数内为常量不可变& Y: M8 n5 k# d- T4 f1 H0 K
这样的一个const引用传递和最普通的函数按值传递的效果是一模一样的,他禁止对引用的对象的一切修改,唯一不同的是按值传递会先建立一个类对象的副本, 然后传递过去,而它直接传递地址,所以这种传递比按值传递更有效.另外只有引用的const传递可以传递一个临时对象,因为临时对象都是const属性, 且是不可见的,他短时间存在一个局部域中,所以不能使用指针,只有引用的const传递能够捕捉到这个家伙
& R4 p0 F& @" a- l (2)const 修饰函数返回值* m- ^$ a( W% X) o; T
const修饰函数返回值其实用的并不是很多,它的含义和const修饰普通变量以及指针的含义基本相同。
) |0 C( p) f. d% G. [ a.const int fun1() //这个其实无意义,因为参数返回本身就是赋值。
: r. |# N, O, v j b. const int * fun2() //调用时 const int *pValue = fun2();
( h/ [; U2 V! t" ~! ]0 M //我们可以把fun2()看作成一个变量,即指针内容不可变。, `5 p3 S0 \4 n* t; \4 [, M
c.int* const fun3() //调用时 int * const pValue = fun2();- k @+ @2 V% m- p
//我们可以把fun2()看作成一个变量,即指针本身不可变。+ [9 x2 }( k0 H! {% Q( n X/ e" ~) V
一般情况下,函数的返回值为某个对象时,如果将其声明为const时,多用于操作符的重载。通常,不建议用const修饰函数的返回值类型为某个对象或对某个对象引用的情况。原因如下:如果返回值为某个对象为const(const A test = A 实例)或某个对象的引用为const(const A& test = A实例),则返回值具有const属性,则返回实例只能访问类A中的公有(保护)数据成员和const成员函数,并且不允许对其进行赋值操作,这在一般情况下很少用到。- ]( k! J& |! J. M D/ U8 E
4、类相关CONST( M# y& m) e, N5 c D
(1)const修饰成员变量5 ?4 m7 }/ t' y5 X ] E" ?
const修饰类的成员函数,表示成员常量,不能被修改,同时它只能在初始化列表中赋值。
6 c! Y" T) P* p# M; G class A
$ {8 V2 i# o& u {
" | f2 G9 T1 K5 d2 ?6 `( \ …! T* S2 l! o0 c; d& |: U/ @4 k N
const int nValue; //成员常量不能被修改$ V, _& h6 y2 @* }% ~, `$ V' b
…5 J. o% M7 s' C% L/ M9 u8 |
A(int x): nValue(x) { } ; //只能在初始化列表中赋值8 W9 N7 f, F! d3 {" D
}
- J: b( f9 o% A3 m (2)const修饰成员函数
3 P% Z# L4 _$ s const修饰类的成员函数,则该成员函数不能修改类中任何非const成员函数。一般写在函数的最后来修饰。0 _& G( T- G) i/ a) q2 o
class A i0 i! J5 [, d2 d
{: |% Y" }% g: C1 }: Q
…8 P2 G, W& x3 Z/ V
void function()const; //常成员函数, 它不改变对象的成员变量.
+ M+ v# ^) V- c/ U" @* x! \9 S //也不能调用类中任何非const成员函数。& } o6 O4 t) j" n# \, T
}7 F& z, E8 N8 i1 X8 x
对于const类对象/指针/引用,只能调用类的const成员函数,因此,const修饰成员函数的最重要作用就是限制对于const对象的使用。</p>a. const成员函数不被允许修改它所在对象的任何一个数据成员。
1 |6 B& U( W, U0 M# o- Z b. const成员函数能够访问对象的const成员,而其他成员函数不可以。0 o5 m {* f1 y, G/ j) u- X; Z5 }
(3)const修饰类对象/对象指针/对象引用
# e. o# g7 b& V0 ^ · const修饰类对象表示该对象为常量对象,其中的任何成员都不能被修改。对于对象指针和对象引用也是一样。
3 M) F+ ~* Q# [ · const修饰的对象,该对象的任何非const成员函数都不能被调用,因为任何非const成员函数会有修改成员变量的企图。
) R+ W& S9 ^& f2 z6 Z: v7 A 例如:9 O- [" H( O' H
class AAA
- h9 o1 {# ^' H; T7 t0 c9 L {6 m m; B8 F% E/ w1 u7 t Z# ~
void func1();
* @, A& z0 C+ p* ] void func2() const;7 X0 T9 |& i- Q9 b
}- D+ }& Z# z1 ] [0 U4 ^
const AAA aObj;- d0 @! O9 b# P" W1 Y
aObj.func1(); ×
1 d, \3 R- }: t4 F aObj.func2(); 正确
M A, B* g6 G6 e const AAA* aObj = new AAA();) M5 u W1 D4 a; B$ }
aObj-> func1(); ×2 N4 Z5 |% D( ?5 N; A8 ?
aObj-> func2(); 正确. P( f+ k1 x3 b8 p& |4 @& z
三、将Const类型转化为非Const类型的方法# S# V' Z: t: J2 g% u8 J
采用const_cast 进行转换。
7 X( K. d% k' w' s4 b- v l 用法:const_cast (expression)$ ?+ q4 {; Y! K @: {& Z
该运算符用来修改类型的const或volatile属性。除了const 或volatile修饰之外, type_id和expression的类型是一样的。7 e n( E9 v, p1 M/ Q# k+ n9 Y
· 常量指针被转化成非常量指针,并且仍然指向原来的对象;: r2 g! e" \ V1 M0 M
· 常量引用被转换成非常量引用,并且仍然指向原来的对象;' d& X8 q% n6 [9 j3 c
· 常量对象被转换成非常量对象 |