C++ 知識總結 P02:修飾
const
常量
使用巨集 define
定義常量是常見的行為,在C++中還可以使用 const
關鍵字來實現常量的定義。
const double PI = 3.1415926535;
在類中使用常量,為了避免每個例項都產生一個常量,可以使用
static const double PI = 3.1415926535
但是在函式中定義的常量,即使重複呼叫函式,也不會發生浪費空間的問題。
常引用、常指標
在某些情況下,如在函式引數傳遞中,為避免使用引用、指標修改指向的變數,可使用如下形式的 const 。此時雖然指向的物件可能是非 const 的,但是無法通過 const 引用或 const 指標修改。
void f(const double& t);
void f(const double* p);
另外,如果目的是防止指標本身被修改,可以使用 double* const p
的形式。(引用沒有這種問題,因為引用無法被修改。)
const
修飾的函式返回值
const
修飾下的函式返回值,可以防止該值被修改,但是接收該函式返回值的變數也必須有 const
屬性。
const int f() {}
const int a = f();
const
修飾的成員函式
被 const
修飾的成員函式,不修改例項的成員變數。另外,如果一個物件例項化為一個常量物件,只能呼叫它的常成員函式。
class TypeSample {
void member() const {}
}
static
靜態全域性變數與靜態區域性變數
使用 static
修飾全域性變數,與無 static
修飾的全域性變數功能相同,區別為被 static
修飾後的全域性變數只能在本檔案中使用,在其他檔案中無法使用。
使用 static
修飾函式內的區域性變數,可以使該變數在函式執行結束時不被銷燬,可以利用靜態區域性變數實現多次函式呼叫間的資訊傳遞。需要強調的是,static
並不改變區域性變數的作用域,也就是說在函式外部是無法訪問靜態區域性變數的。
靜態函式
在函式的宣告前加上 static
修飾,作用與靜態全域性變數相同,使該函式只能在本檔案中使用,在其他檔案中無法使用。
靜態成員變數與靜態成員函式
使用 static
修飾的類成員變數,與普通的成員變數的區別是:普通成員變數是屬於例項的,但是靜態成員變數是屬於類的,是類的所以例項所共有的。可以用來存放類的常量,以及僅與類本身相關的屬性。
同樣的,靜態成員函式是屬於類的,與普通的成員函式的區別是:普通成員函式都隱含了 this
指標,該指標指向例項本身,用來訪問例項的成員變數和成員函式,但 this
指標不是指向類的,故靜態成員函式沒有 this
指標。這種區別造成了靜態成員函式只能訪問靜態成員變數,也只能呼叫靜態成員函式,但普通成員函式沒有這種限制;另外可以使用 class_name::static_func()
的方式直接呼叫靜態成員函式。
extern
使用外部變數
如果需要在某個工程檔案中使用其它檔案中定義的變數,可以使用extern指定。在需要使用外部變數的地方,放置一個 extern
修飾的變數宣告即可。
#include "other.h"
extern int param; // 此變數在 other.h 中有定義
使用 C 的程式碼
extern
的另一個使用方法是在 C++ 中使用 C 的程式碼。在需要使用 C 的地方,使用 extern "C"
告知編譯器。
extern "C" {
#include "c_code.h"
}
// 如果只想使用其中的一個函式
extern "C" {
int c_function(int);
}
constexpr
const
關鍵字並沒有明確說明是在編譯期間為常量還是在執行期間為常量,constexpr
告知編譯器該語句或函式在編譯期間就是常量,也就是說這些語句或函式在編譯期間就可以計算出來。constexpr
比 const
更為嚴格,但是能夠讓編譯器對程式碼進行更多的優化,在能使用 constexpr
的情況下推薦使用 constexpr
代替 const
。
auto 與 decltype()
auto
關鍵字用於宣告變數時自動推導變數的型別,適合冗長的變數型別,過多的使用 auto
會造成程式碼可讀性下降,另外某些情況下 auto
可能存在歧義,為後續程式碼帶來隱患。
decltype()
也是用於推導變數的型別,用於已經存在的變數。
auto iter = vec.begin();
using Iter = decltype(iter);