程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> const用法總結,const用法

const用法總結,const用法

編輯:C++入門知識

const用法總結,const用法


1. const修飾變量

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修飾指針本身時必須初始化。

2. const在函數中的使用

2.1 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 &傳遞”。

2.2 const修飾函數返回值

如果給“指針傳遞”的函數返回值加const修飾符,那麼返回值是一種契約性常量,不能被直接修改,並且該返回值只能被賦值給加const修飾的同類型指針(除非強制轉換),例如:

const char* GetString(void);  //函數聲明
char* str = GetString();  //編譯錯誤
const char* str = GetString();  //正確

如果函數返回值采用“值傳遞”的方式,在一般情況下由於函數會把返回值拷貝到外部的臨時存儲單元中,所以加const修飾是沒有什麼意義的。

2.3 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;

3. const與#define比較

第一: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是內部連接的

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved