Effective C++ 條款01:視 C++ 為一個語言聯邦
核心思想:C++ 是由多個子語言組成的聯邦,每個子語言有自己的編程范式。理解這些子語言及其規則切換,是寫出高效 C++ 代碼的關鍵。
四個子語言及其規則:
- C 語言
- 基礎:過程式編程,包含指針、數組、預處理等。
- 規則:按值傳遞高效(如內置類型)。
- 面向對象 C++
- 核心:類、封裝、繼承、多態、虛函數。
- 規則:優先按
const
引用傳遞對象。
- 模板 C++
- 特性:泛型編程、模板元編程。
- 規則:編譯期推導類型,需注意依賴類型(
typename
)。
- STL(標準模板庫)
- 組件:容器、迭代器、算法、函數對象。
- 規則:迭代器按值傳遞(類似指針)。
代碼示例
1. C 語言部分:內置類型按值傳遞
#include <iostream>// 內置類型高效按值傳遞
void printInt(int val) { // 推薦:直接傳遞 intstd::cout << "Value: " << val << std::endl;
}int main() {int x = 42;printInt(x); // 高效拷貝return 0;
}
2. 面向對象 C++:對象按 const
引用傳遞
#include <string>class Person {
public:Person(std::string name) : name_(std::move(name)) {}virtual ~Person() = default;virtual std::string role() const { return "Person"; }protected:std::string name_;
};class Student : public Person {
public:using Person::Person;std::string role() const override { return "Student"; }
};// 按 const 引用傳遞避免拷貝和多態失效
void printRole(const Person& p) { // 正確:支持多態,無拷貝std::cout << p.role() << std::endl;
}int main() {Student s("Alice");printRole(s); // 輸出 "Student"(多態生效)return 0;
}
3. 模板 C++:使用 typename
聲明依賴類型
#include <vector>template<typename T>
class Container {
public:using Iterator = typename T::iterator; // 必須用 typenamestatic Iterator begin(T& container) {return container.begin();}
};int main() {std::vector<int> vec = {1, 2, 3};auto it = Container<std::vector<int>>::begin(vec);return 0;
}
4. STL:迭代器按值傳遞
#include <vector>
#include <algorithm>// 迭代器按值傳遞(類似指針)
template<typename Iter>
void printFirstTwo(Iter begin, Iter end) {if (begin != end) {std::cout << *begin << " ";++begin;}if (begin != end) {std::cout << *begin << std::endl;}
}int main() {std::vector<int> nums = {10, 20, 30};printFirstTwo(nums.begin(), nums.end()); // 輸出 "10 20"return 0;
}
關鍵總結
子語言 | 典型場景 | 參數傳遞規則 |
---|---|---|
C 語言 | 內置類型、指針、數組 | 按值傳遞 |
面向對象 C++ | 類、繼承、虛函數 | 按 const 引用傳遞 |
模板 C++ | 泛型編程、元編程 | 依賴類型用 typename |
STL | 容器、迭代器、算法 | 迭代器按值傳遞 |
編程啟示:在切換子語言時(如從 STL 迭代器切換到面向對象),需同步切換編程策略,避免效率損失或錯誤。