改編自
http://baike.sogou.com/v64494396.htm?fromTitle=CONST
http://blog.csdn.net/lihao21
http://blog.sina.com.cn/s/blog_79b01f6601018xdg.html
- const與#define宏定義的對比:
const可以節(jié)省空間碴犬,避免不必要的內(nèi)存分配。(const是為了消除#define的缺點而產(chǎn)生的)
例如:
#define PI 3.14159 //常量宏
double I=PI; //編譯期間進行宏替換寇壳,分配內(nèi)存
double J=PI; //再進行宏替換,又一次分配內(nèi)存!
const double Pi=3.14159; //此時并未將Pi放入RAM中
double i=Pi; //此時為Pi分配內(nèi)存,以后不再分配偿乖!
double j=Pi; //沒有內(nèi)存分配
const定義常量從匯編的角度來看,只是給出了對應(yīng)的內(nèi)存地址哲嘲,而不是像#define一樣給出的是立即數(shù)贪薪,所以,const定義的常量在程序運行過程中只有一份拷貝眠副,而#define定義的常量在內(nèi)存中有若干份拷貝画切。
- const常用用法:左定值,右定向
1)const在前面
const int nValue囱怕; //nValue是const
const char *pContent; //*pContent是const, pContent可變
const char* const pContent; //pContent和*pContent都是const
2)const在后面霍弹,與上面的聲明對等
int const nValue; //nValue是const
char const * pContent; //*pContent是const, pContent可變
char* const pContent; //pContent是const,*pContent可變
char const* const pContent; //pContent和*pContent都是const
const只修飾其后的變量,至于const放在類型前還是類型后并沒有區(qū)別娃弓。如:const int a和int const a都是修飾a為const典格。
3)指針指向的變量的值不能變,指向可變(左定值)
int x = 1;
int y = 2;
const int* px = &x;
int const* px = &x; //這兩句表達式一樣效果
px = &y; //正確台丛,允許改變指向
*px = 3; //錯誤耍缴,不允許改變指針指向的變量的值
4)指針指向的變量的值可以改變,指向不可變(右定向)
int x = 1;
int y = 2;
int* const px = &x;
px = &y; //錯誤挽霉,不允許改變指針指向
*px = 3; //正確防嗡,允許改變指針指向的變量的值
5)指針指向的變量的值不可變,指向不可變
int x = 1;
int y = 2;
const int* const px = &x;
int const* const px = &x;
px = &y; //錯誤侠坎,不允許改變指針指向
*px = 3; //錯誤蚁趁,不允許改變指針指向的變量的值
6)
typedef char * pStr;
char string = "bbc";
const char *p1 =" string"; //1式
const pStr p2 =" string"; //2式
p1++;
p2++;
答案:const使用的基本形式: const type m;限定m不可變。替換基本形式中的m為1式中的*p1实胸,替換后const char *p1;限定*p1不可變荣德,當然p1是可變的闷煤,因此問題中p1++是對的。替換基本形式中的type為2式中的pStr涮瞻,替換后const pStr m;限定m不可變鲤拿,題中的pStr就是一種新類型,因此問題中p2不可 變署咽,p2++是錯誤的近顷。
7)在c中,對于const定義的指針宁否,不賦初值編譯不報錯窒升,
int* const px;這種定義是不允許的。(指針常量定義的時候?qū)ζ溥M行初始化慕匠,右定向饱须,必須指定指針指向)
int const *px;這種定義是允許的。(常指針可以再定義的時候不初始化台谊,左定值蓉媳,可以不賦初值)
- const成員函數(shù): 若將成員成員函數(shù)聲明為const,則該函數(shù)不允許修改類的數(shù)據(jù)成員锅铅。
在C++中酪呻,只有被聲明為const的成員函數(shù)才能被一個const類對象調(diào)用。
const Screen blankScreen;
blankScreen.display(); // 對象的讀操作
blankScreen.set(‘*’); // 錯誤:const類對象不允許修改
1)值得注意的是盐须,把一個成員函數(shù)聲明為const可以保證這個成員函數(shù)不修改數(shù)據(jù)成員玩荠,但是,如果據(jù)成員是指針贼邓,則const成員函數(shù)可以修改指針指向的對象阶冈。
2)const成員函數(shù)可以訪問非const對象的非const數(shù)據(jù)成員、const數(shù)據(jù)成員塑径,也可以訪問const對象內(nèi)的所有數(shù)據(jù)成員眼溶;
3)非const成員函數(shù)可以訪問非const對象的非const數(shù)據(jù)成員、const數(shù)據(jù)成員晓勇,但不可以訪問const對象的任意數(shù)據(jù)成員;
4)作為一種良好的編程風(fēng)格灌旧,在聲明一個成員函數(shù)時绑咱,若該成員函數(shù)并不對數(shù)據(jù)成員進行修改操作,應(yīng)盡可能將該成員函數(shù)聲明為const 成員函數(shù)枢泰。
- 在const成員函數(shù)中描融,用mutable修飾成員變量名后,就可以修改類的成員變量了衡蚂。
- 類中的常量:有時我們希望某些常量只在類中有效窿克。由于#define定義的宏常量是全局的骏庸,不能達到目的,于是想當然地覺得應(yīng)該用const修飾數(shù)據(jù)成員來實現(xiàn)年叮。const數(shù)據(jù)成員的確是存在的具被,但其含義卻不是我們所期望的。const數(shù)據(jù)成員只在某個對象生存期內(nèi)是常量只损,而對于整個類而言卻是可變的一姿,因為類可以創(chuàng)建多個對象,不同的對象其const數(shù)據(jù)成員的值可以不同跃惫。
不能在類聲明中初始化const數(shù)據(jù)成員叮叹。以下用法是錯誤的,因為類的對象未被創(chuàng)建時爆存,編譯器不知道SIZE的值是什么蛉顽。
class A
{…
const int SIZE = 100; // 錯誤,企圖在類聲明中初始化const數(shù)據(jù)成員
int array[SIZE]; // 錯誤先较,未知的SIZE
};
const數(shù)據(jù)成員的初始化只能在類構(gòu)造函數(shù)的初始化表中進行携冤,例如
class A
{…
A(int size); // 構(gòu)造函數(shù)
const int SIZE ;
};
A::A(int size) : SIZE(size) // 構(gòu)造函數(shù)的初始化表
{
…
}
A a(100); // 對象 a 的SIZE值為100
A b(200); // 對象 b 的SIZE值為200
怎樣才能建立在整個類中都恒定的常量呢?別指望const數(shù)據(jù)成員了拇泣,應(yīng)該用類中的枚舉常量來實現(xiàn)噪叙。例如
```
class A
{…
enum { SIZE1 = 100, SIZE2 = 200}; // 枚舉常量
int array1[SIZE1];
int array2[SIZE2];
};
枚舉常量不會占用對象的存儲空間,它們在編譯時被全部求值霉翔。枚舉常量的缺點是:它的隱含數(shù)據(jù)類型是整數(shù)睁蕾,其最大值有限,且不能表示浮點數(shù)(如PI=3.14159)债朵。sizeof(A) = 1200;其中枚舉部長空間子眶。
```enum EM { SIZE1 = 100, SIZE2 = 200}; // 枚舉常量 sizeof(EM) = 4;```