Effective C++ 条款01:视 C++ 为一个语言联邦
Effective C++ 条款01:视 C++ 为一个语言联邦
核心思想:C++ 是由多个子语言组成的联邦,每个子语言有自己的编程范式。理解这些子语言及其规则切换,是写出高效 C++ 代码的关键。
四个子语言及其规则:
- C 语言
- 基础:过程式编程,包含指针、数组、预处理等。
- 规则:按值传递高效(如内置类型)。
- 面向对象 C++
- 核心:类、封装、继承、多态、虚函数。
- 规则:优先按
const
引用传递对象。
- 模板 C++
- 特性:泛型编程、模板元编程。
- 规则:编译期推导类型,需注意依赖类型(
typename
)。
- STL(标准模板库)
- 组件:容器、迭代器、算法、函数对象。
- 规则:迭代器按值传递(类似指针)。
代码示例
1. C 语言部分:内置类型按值传递
#include // 内置类型高效按值传递void printInt(int val) { // 推荐:直接传递 int std::cout << \"Value: \" << val << std::endl;}int main() { int x = 42; printInt(x); // 高效拷贝 return 0;}
2. 面向对象 C++:对象按 const
引用传递
#include 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 template<typename T>class Container {public: using Iterator = typename T::iterator; // 必须用 typename static 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 #include // 迭代器按值传递(类似指针)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;}
关键总结
const
引用传递typename
编程启示:在切换子语言时(如从 STL 迭代器切换到面向对象),需同步切换编程策略,避免效率损失或错误。