inline關鍵字於定義處(聲明處無效)
#define DEBUG(X) cout << #X << "=" << X
DEBUG(var); // 展開為 cout << "var" << "=" << var;
#X將參數轉為字符串字面值。
#include
assert(condition); // 條件為假 → 終止程序,輸出文件名、行號、條件表達式
僅調試構建生效(NDEBUG宏控制),釋放版自動消失,零開銷。
main返回或exit()調用時,逆序構造順序析構exit() → 可能死循環(重入析構)abort():直接終止,不調用任何析構函數atexit(fn):註冊main返回/exit時調用的函數,優先於靜態對象析構執行
void exit_fn2() { printf("Exit #2\n"); }
atexit(exit_fn2); // 註冊
main前構造,main後析構int a; → 外部鏈接(extern可見)static int b; → 內部鏈接(僅本文件可見)int X::s = 23;(.cpp中,無視訪問權限)
namespace math {
enum sign { positive, negative };
class integer { ... };
integer A, B, C;
integer divide(integer, integer);
}
void q() {
using namespace math; // 引入整個命名空間
integer A; // 隱藏math::A
A.Sign(negative);
math::A.Sign(positive); // 顯式限定訪問被隱藏名字
}
作用:大型項目防止名字衝突,模塊化封裝。
22. extern "C" 與 extern "C++"
- C++編譯器修飾函數名(如
_f_int_int),C編譯器不修飾(_f)
- 鏈接C庫:
extern "C" { #include "c_header.h" }
extern "C++" {} 顯式指定C++鏈接(默認即是)
23. 引用傳參本質
函數調用時,傳引用本質也是壓指針入棧,語法糖而已。
24. 四大函數調用順序實測
class X {
X() { cout << "construct"; } // 構造
X(const X&) { cout << "copy_struct"; } // 拷貝構造
X& operator=(const X&) { cout << "operator="; return *this; } // 賦值
~X() { cout << "destruct"; } // 析構
};
場景A:X x; X a = x;(定義時初始化 → 拷貝構造)
construct // x
copy_struct // a
場景B:X x; X a; a = x;(先構造再賦值)
construct // x
construct // a
copy_struct // 臨時對象?視編譯器優化(NRV/RVO)
operator= // 賦值
destruct // 臨時對象析構
無拷貝構造時:直接construct, construct, operator=, destruct。
關鍵:X a = x;調用拷貝構造,不調用默認構造+賦值。
25. 成員指針語法
成員函數指針
class X { int a(void); };
X x;
int (X::*pf)(void) = &X::a; // 取地址
(x.*pf)(); // 調用
成員變量指針
class X { int i; };
int X::*pm = &X::i; // 類作用域取地址
X x;
x.*pm = 10; // 通過對象訪問
總結
下集涵蓋:編譯期機制、對象生命周期管理、名字空間模塊化、C/C++互操作、成員指針元編程基礎。掌握這些,C++底層功力將質躍升級。