int b = 100; const int* a = &b; //情況1 int const* a = &b; //情況2 int* const a = &b; //情況3 const int* const a = &b; //情況4
const修飾有三種情況:
第一:const在“ * ”左邊,則const用來修飾指針所指向的變量,即指針指向為常量,如情況1,情況2;
第二:const在“ * ”右邊,則const用來修飾指針本身,即指針本身是常量,如情況3;
第三:const在“ * ”兩邊,則const既修飾指針本身也修飾指針所指變量,如情況4;
注意:const的相對位置只與“ * ”有關,和變量的類型聲明沒有位置關系,其次const修飾指針所指變量時可以不初始化,但const修飾指針本身時必須初始化。
輸入參數采用“指針傳遞”,那麼加const修飾可以防止意外的改動該指針指向的內存單元,起到保護作用,如StringCopy函數
//輸入參數: strSrc 輸出參數:strDest void StringCopy(char* strDest, const char* strSrc);
如果還想保護指針本身,則可以聲明指針本身為常量,例如:
void OutputString(const char* const pStr);
如果參數用於輸出,不論它是什麼類型,也不論它采用“指針傳遞”還是“引用傳遞”,都不能加const修飾,即const只能修飾輸入參數。另外如果如果輸入參數采用“值傳遞”,由於函數將自動用實參的拷貝初始化形參,因此即使在函數內部修改了該參數,改變的也只是堆棧上的拷貝而不是實參,所以一般不需要const修飾。最好不要把void Func(const int x)改為void Func(const int &x)這樣即達不到提高效率的目的有讓人費解。因為基本數據類型的參數不存在構造、析構的過程,除基本類型參數為推薦使用“const &傳遞”。
如果給“指針傳遞”的函數返回值加const修飾符,那麼返回值是一種契約性常量,不能被直接修改,並且該返回值只能被賦值給加const修飾的同類型指針(除非強制轉換),例如:
const char* GetString(void); //函數聲明 char* str = GetString(); //編譯錯誤 const char* str = GetString(); //正確
如果函數返回值采用“值傳遞”的方式,在一般情況下由於函數會把返回值拷貝到外部的臨時存儲單元中,所以加const修飾是沒有什麼意義的。
class CTextBlock { public: ... std::size_t length() const; private: char* pText; std::size_t textLength; bool lengthIsValid; }; std::size_t CTextBlock::length() const { if(!lengthIsValid) { textLength = std::strlen(pText); //錯誤,const成員函數不能給類中的 lengthIsValid = true; //成員變量賦值 } return textlength; }
const成員函數不能給類中的成員變量賦值,如果非得給類中成員變量賦值,可以用mutable來修飾成員變量,如:
mutable std::size_t textLength; mutable bool lengthIsValid;
第一:const常量有數據類型,而宏常量沒有數據類型。編譯器可以對前者進行類型安全檢查而對後者只能進行字符替換,沒有安全類型檢查,並且替換中可能會出現意料不到的錯誤(邊際效應)。
第二:編譯處理宏定義時,在預編譯時將實際將所有宏定義全部替換成成實際值然後進行編譯,const修飾的值在編譯期間的常量,同時const常量可能比define產生更小的代碼量。
第三:有些集成化調試工具可以對const常量進行調試,但不能對宏常量進行調試。
第四:#define不能創建一個class專屬常量,也不能提供任何封裝性,const可以定義class專屬常量,如:
class GamePlayer { private: static const int NumTurns = 5; int scores[NumTurns]; }
建議:對於單純常量,最好以const對象或enums替換#define;對應形似函數的宏,最好用inline函數替換#define。
補充知識:
C中的const是“一個不能被改變的普通變量”,它總是占用內存,而且它是全局變量,C編譯器不能把const看成一個變異期間的常量,在C中下面的函數是不合理的
const bufsize = 100; char buf[bufsize];
而在C++中是正確的,C默認const是外部連接的,C++默認const是內部連接的