1. 程式人生 > 實用技巧 >C++ 知識總結 P02:修飾

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 告知編譯器該語句或函式在編譯期間就是常量,也就是說這些語句或函式在編譯期間就可以計算出來。constexprconst 更為嚴格,但是能夠讓編譯器對程式碼進行更多的優化,在能使用 constexpr 的情況下推薦使用 constexpr 代替 const

auto 與 decltype()

auto 關鍵字用於宣告變數時自動推導變數的型別,適合冗長的變數型別,過多的使用 auto 會造成程式碼可讀性下降,另外某些情況下 auto 可能存在歧義,為後續程式碼帶來隱患。

decltype() 也是用於推導變數的型別,用於已經存在的變數。

auto iter = vec.begin();
using Iter = decltype(iter);