const 定義普通變量
# define PI 3.1415926
const double Pi = 3.1415926;
效果上看,使用 #define
和 const
定義的普通常量效果一致。但是內部實現上,還是有區別
const
會進行類型檢查而#define
不會,因此const
更安全const
定義的變量只有在被引用時才被分配內存,而且只分配一次,之後傳遞的都是指針。而#define
作爲宏定義每次用到都會立即分配相應內存,因此const
更節省空間,避免了重複分配相同內容的內存空間- 編譯器通常不爲普通
const
常量分配存儲空間,而是保存在符號表中,這使得它成爲一個編譯期間的常量,沒有了讀寫內存的操作,效率極高。
結論: 能用 const 就多用 const
const 定義指針變量
符合類型要從右往左看,
// pContent本身是const常量指針,就指向一個固定的內存地址,但是內存裏的內容是可以修改的
char * const pContent;
char const * pContent;
// pContent本身是一個普通指針,但指向的內容是一個(const char) 的不可變常量
const char * pContent;
// 都不可變
const char* const pContent;
const 修飾函數
const 修飾函數參數
使用引用傳參,增加效率同時防止修改
void foo(const TYPE& Var);
const 修飾函數返回值
一般不建議採用
// 無意義,因爲參數返回本身就是賦值
const int foo();
// 對應的調用是 const int * p = foo2()
const int * foo2();
// 對應的調用是 int * const p = foo3()
int * const foo3();
const 類相關操作
const 修飾類成員變量
表示成員變量不能被修改,而且只能在初始化列表中賦值。
class A
{
const int i; // 定義常量成員函數
A(int value): i(value) {} // 只能在初始化列表中賦初值
};
const 修飾類成員函數
表明此函數不會修改類中的任何成員變量
class A
{
void foo() const;
};
外部使用時的 const 的類對象/指針/引用等等,都只能調用類的 const成員函數。防止對類中成員變量的修改。
class A
{
void foo(); // 普通成員函數
void bar() const; //const 成員函數
};
void fun(const A& a)
{
a.foo(); //error
a.bar(); // OK
}
const 類型轉化爲非const類型
使用 const_cast
進行轉換
Best Practice
- 在搞懂
const
基本原理的前提下,放心大膽,多多益善地使用const
- 在函數參數中,應該更多地使用
const
引用或指針,const
一般的對象實例是沒有意義的 - 任何不會修改成員變量的成員函數都應該聲明爲
const
類型
Ref
- 關於C++ const 的全面總結: 超級好文,全面的梳理總結
- C++中const和引用修飾變量和函數的總結: 代碼示例多一些,
const 指針
與&引用
的區別說的非常好 - const成員變量與成員函數 : 簡單的個人實踐總結