作為一個(gè)基本知識(shí)點(diǎn),要理解const char * const p的含義。第一個(gè)const代表p所指向的存儲(chǔ)區(qū)域是常量,當(dāng)初始化后不可以被修改;第二個(gè)const代表的是變量p一旦指向了某個(gè)存儲(chǔ)區(qū)域后,它就不可以指向別的區(qū)域。
在我的文章里面,經(jīng)常會(huì)看到char const* p或者int const a這種用法。他們等價(jià)于const char* p和const int a。
const char* p和 char const* p都代表p指向的內(nèi)存區(qū)域是常量,const都是修飾char類型的,但是顯然后者更明顯。我們應(yīng)該把const看成是對(duì)前面類型的修飾,這樣const將char和*p很自然的分隔開(kāi)來(lái)。
char * const p中,const修飾char*類型,代表該指針是不可變的常量指針。
你不覺(jué)得這種做法和修飾函數(shù)的做法一樣么?你肯定見(jiàn)過(guò)void A::f() const的用法。
在typedef的使用中,后置const的用法不會(huì)產(chǎn)生感覺(jué)上的混亂,比如:
typedef char* CHARS;
typedef const CHARS CPTR;//指向char類型的常量指針,不要覺(jué)得奇怪,事實(shí)就是這樣。來(lái)看下面的例子:
typedef char* CHARS;
typedef const CHARS CPTR;
int _tmain(int argc, _TCHAR* argv[])
{
CPTR p="a";
p="b";
return 0;
}
error C3892: 'p' : you cannot assign to a variable that is const
有一天,我們忽然用CHARS的等價(jià)形式修改了第二句話
typedef const char* CPTR;
typedef char* CHARS;
typedef const char* CPTR;
int _tmain(int argc, _TCHAR* argv[])
{
CPTR p="a";
p="b";
return 0;
}
正確。問(wèn)題出在typedef const char* CPTR;和typedef const CHARS CPTR;居然不等價(jià)。當(dāng)你用后置const來(lái)表示,混亂就消失了。
typedef char* CHARS;
typedef CHARS const CPTR;
int _tmain(int argc, _TCHAR* argv[])
{
CPTR p="a";
p="b";
return 0;
}
和下面的
typedef char* CHARS;
typedef char* const CPTR;
int _tmain(int argc, _TCHAR* argv[])
{
CPTR p="a";
p="b";
return 0;
}
都會(huì)報(bào)同樣的錯(cuò)誤,error C3892: 'p' : you cannot assign to a variable that is const。
我們應(yīng)該習(xí)慣多用const,并且知道何時(shí)不該濫用。
1)如果一個(gè)類的成員函數(shù)不會(huì)修改內(nèi)部數(shù)據(jù),用const修飾這是一種提醒,并且也會(huì)帶來(lái)方便。比如下面的代碼中,如果你不加const修飾函數(shù),就會(huì)遇到麻煩:
class A
{
public:
void f()
{}
};
void Sample(A const& a)
{
a.f();
}
int _tmain(int argc, _TCHAR* argv[])
{
A a;
Sample(a);
return 0;
}
error C2662: 'A::f' : cannot convert 'this' pointer from 'const A' to 'A &'
而像Sample這樣的函數(shù)你有很大的幾率遇到。
2)我們也有可能寫(xiě)Sample這樣的函數(shù),當(dāng)我們的參數(shù)是值傳遞時(shí),不要用const,因?yàn)檫@不會(huì)帶來(lái)好處,還會(huì)帶來(lái)誤導(dǎo),當(dāng)我們的參數(shù)是引用或者指針時(shí),使用const修飾,明確告訴用戶傳址以提高效率,但是決不會(huì)在函數(shù)內(nèi)部修改。
3)如果你不想讓別人對(duì)你的函數(shù)返回值作修改,給它一個(gè)const修飾符也不錯(cuò)
4)哲學(xué)上,const可以被理解為物理常量和邏輯常量,當(dāng)一個(gè)成員函數(shù)被修飾為const,物理常量的理解認(rèn)為該函數(shù)內(nèi)部絕不可以修改類的成員,邏輯常量理論認(rèn)為,出于優(yōu)化的目的,你可以悄悄地修改某個(gè)變量,只要不讓客戶感覺(jué)到就可以。我站在邏輯常量這一邊。如果你想要在一個(gè)const成員函數(shù)內(nèi)修改某個(gè)變量,你需要為這個(gè)變量加上一個(gè)修飾符mutable。比如:
class A
{
public:
void f() const
{
_f=2;
}
private:
mutable int _f;
};
int _tmain(int argc, _TCHAR* argv[])
{
A a;
a.f();
return 0;
}
我們有時(shí)候需要進(jìn)行const相關(guān)的類型轉(zhuǎn)換
從非const引用(或者指針)到const引用是自動(dòng)完成的。例如:
char* p="f";
char const* p2=p;
反過(guò)來(lái)去掉const約束的時(shí)候,你需要const_cast轉(zhuǎn)換符
char const* p="f";
char* p2=const_cast<char*>(p);
聯(lián)系客服