C++ 並非 C 的簡單超集,而是在兼容大多數 C 代碼的基礎上,引入面向對象、泛型編程、RAII 資源管理、標準庫等現代語言特性。本文從關鍵字、類型系統、內存管理、輸入輸出、函數特性、作用域規則六大維度,系統梳理兩語言核心差異,助 C 程序員平滑遷移、C++ 開發者夯實基本功。
C++98/11/14/17/20 累計新增 60+ 關鍵字,核心新增:
| 分類 | 關鍵字示例 |
|---|---|
| 面向對象 | class, virtual, override, final, public, protected, private, this, friend |
| 泛型編程 | template, typename, concept, requires |
| 內存管理 | new, delete, new[], delete[], alignas, alignof |
| 異常處理 | try, catch, throw, noexcept |
| 類型系統 | bool, wchar_t, char16_t, char32_t, char8_t, decltype, nullptr |
| 類型轉換 | static_cast, dynamic_cast, const_cast, reinterpret_cast |
| 命名空間 | namespace, using |
| 其他 | inline, constexpr, consteval, constinit, static_assert, decltype, auto |
影響:C 代碼若用上述詞作變量名,C++ 編譯失敗。
bool 原生類型C 用 int 模擬,C++ true/false 為關鍵字,轉換規則:0→false,非0→true。sizeof(bool) 實現定義 (通常 1)。
wchar_t / Unicode 字符類型wchar_t 為獨立類型 (非 typedef),配合 wcin/wcout/wstring 處理多字節字符。C++11 新增 char16_t/char32_t (UTF-16/32),C++20 新增 char8_t (UTF-8)。
enum 定義獨立作用域類型,隱式轉換為 int,但 int 不能隱式轉枚舉。enum class (強類型枚舉) :無隱式轉換、作用域隔離 (Color::Red)、可指定底層類型 (enum class Flag : uint8_t)。| 特性 | malloc/free | new/delete |
|---|---|---|
| 性質 | 庫函數 | 運算符 (可重載) |
| 類型安全 | 返回 void* 需強轉 | 返回具體類型指針 |
| 構造/析構 | 無 | 自動調用 |
| 失敗行為 | 返回 NULL | 拋 std::bad_alloc (或 nothrow 版返回 nullptr) |
| 數組支持 | 手動計算大小 | new T[N] / delete[] p |
| 定位構造 | 無 | new (ptr) T(args) (Placement new) |
鐵律:new 配 delete,new[] 配 delete[],malloc 配 free,嚴禁混用。對象語義場景強制使用 new/delete 保證構造/析構調用。
// C 風險:格式字符串與參數不匹配導致 UB
printf("%d", 3.14); // 未定義行為
// C++ 類型安全:運算符重載自動匹配類型
std::cout << 3.14; // 自動調用 double 版本
std::cout << obj; // 用戶定義 operator<< 即可支持
std::cout << std::hex << 255 << '\n'; // ff
std::cout << std::setw(10) << std::setfill('0') << 42; // 0000000042
默認同步 stdio (可 std::ios::sync_with_stdio(false) 關閉提速),cin.tie(nullptr) 解綁 cout 刷新。
同名函數通過參數列表 (類型/個數/順序) 区分,返回類型不參與重載。C 需前綴區分 (print_int, print_double)。
void func(int a = 10, double b = 3.14);
func(); // a=10, b=3.14
func(5); // a=5, b=3.14
func(5, 2.0);// a=5, b=2.0
C 無此特性,需用宏或多函數模擬。
inline 建議編譯器展開調用點,替代 C 的函數式宏,擁有類型檢查、作用域、調試支持。
T&:對象別名,必須初始化,不可重綁定,避免拷貝開銷,實現輸出參數。T&& (C++11):綁定臨時對象,啟用移動語義、完美轉發。void swap(int& a, int& b) { int t=a; a=b; b=t; } // 引用參數,無拷貝
int&& r = 42; // 延長臨時對象壽命
| 規則 | C | C++ |
|---|---|---|
| 變量聲明位置 | 塊開頭 (C89) / 任意位置 (C99) | 任意位置,就近聲明原則 |
| for 循環變量作用域 | 循環外可見 (C89) / 循環內 (C99) | 循環內 (for(int i=0;...)) |
| 結構體標簽空間 | 獨立標簽空間 (struct A) | 與普通標識符共享 (A a; 直接用類型名) |
| const 對象鏈接屬性 | 外部鏈接 | 內部鏈接 (需 extern 導出) |
| 字符串字面量類型 | char[] (可修改 UB) | const char[] (不可修改) |
struct 默認 public,class 默認 private;支援成員函數、繼承、虛函數、訪問控制。namespace ns { ... } 解決全局命名衝突,C 無對應機制。try/catch/throw 替代 setjmp/longjmp,支援棧展開、RAII 自動清理。string, smart_ptr, thread, regex, filesystem... C 僅有 libc。main 返回類型:C++ 必須 int,C 允許隱式 int (C99 強制 int)。從 C 到 C++ 不僅是語法增量,更是編程篩式轉換:手動資源管理 → RAII 自動化;巨集/指針運算 → 模板/引用/智能指針類型安全;面向過程 → 多範式 (OOP/GP/函數式)。理解差異本質,方能寫出地道、高效、安全的現代 C++ 代碼。