類型推導佔位符,**變量必須初始化**,編譯期替換為實際類型。
auto x = 5; // int auto p = new auto(1); // int* const auto* v = &x; // const int* auto& ref = x; // int& auto&& uref = x; // int& (左值引用) // auto int y; // 錯誤:C++11 起不再作為存儲類別
推導規則:非引用/指針聲明時忽略頂層 const/volatile;聲明為引用/指針時保留 cv 資格。
編譯期推導**表達式類型**,不求值。語法:decltype(expr)。
int x = 0; decltype(x) y = 1; // int const int& r = x; decltype(r) z = y; // const int& decltype((x)) w = y; // int& (加括號視為左值表達式) decltype(x + y) z2; // int (右值表達式) int* p = &x; decltype(*p) z3 = x; // int& (解引用為左值)
三大規則:① 標識符/成員訪問 → 類型本身 ② 函數調用 → 返回類型 ③ 左值表達式 → T&,否則 → T。
修飾**單參數構造函數**或**轉換函數**,禁止隱式轉換。
class String {
public:
explicit String(int n); // 禁止 String s = 10;
explicit operator bool() const; // C++11 禁止 if(s) 隱式轉換
};
構造函數定義體外不再重複 explicit。多參數構造無需 explicit(無隱式轉換場景)。
建議編譯器內聯展開,**定義必須可見**(通常置於頭文件)。類內定義隱式 inline。遞歸函數一般不內聯。
聲明**常量表達式**函數/變量,編譯期求值。
constexpr int square(int x) { return x * x; }
constexpr int sz = square(5); // 編譯期計算 25
int arr[sz]; // 合法:sz 為常量表達式
// C++14 允許較複雜函數體
constexpr int factorial(int n) {
int res = 1;
for (int i = 2; i <= n; ++i) res *= i;
return res;
}
隱含 inline。參數/返回類型須為字面類型。運行時參數調用不保證編譯期求值。
int A::cnt = 0;const static 整型可在類內初始化,C++17 起 inline static 可在類內定義this,只能訪問靜態成員,不可 const/virtualregister:建議寄存器分配,現代編譯器自動優化,C++17 棄用。
volatile:告知編譯器**不可優化訪問**,每次從內存讀寫。用於硬件寄存器、信號處理、多線程標誌位(但不保證原子性/內存序,需配合 std::atomic)。
| 運算符 | 用途 | 運行時檢查 |
|---|---|---|
static_cast | 相關類型轉換(基類↔派生類、算術類型、void*↔T*) | 無 |
dynamic_cast | 多態類層次下行轉換(基類*→派生類*) | 有,失敗返回 nullptr/拋 bad_cast |
const_cast | 移除/添加 const/volatile | 無 |
reinterpret_cast | 無關類型位模式重新解釋(指針↔整數、函數指針轉換) | 無 |
// dynamic_cast 典型用法
class Base { virtual ~Base() = default; };
class Derived : public Base {};
Base* b = new Derived;
Derived* d = dynamic_cast<Derived*>(b); // 成功
Base* b2 = new Base;
Derived* d2 = dynamic_cast<Derived*>(b2); // 失敗,返回 nullptr
class Point {
double x, y;
friend double Distance(const Point&, const Point&); // 普通函數
friend class Debugger; // 整個類
};
virtual,派生類自動為虛函數(建議加 override)inline/static/構造函數不可 virtual=0 使類成為抽象類,不可實例化