侯捷C++系列课程学习笔记
目录
一、面向对象编程(Object-Oriented Programming)
二、内存管理(Memory Management)
三、模板与泛型编程(Templates & Generic Programming)
四、STL(Standard Template Library)
五、C++对象模型(Object Model)
六、C++11/14/17新特性
七、学习建议
一、面向对象编程(Object-Oriented Programming)
-
封装(Encapsulation)
-
类与对象的关系:类为蓝图,对象为实例。
-
访问控制:
public
/protected
/private
的作用域差异。 -
成员函数与数据成员的初始化顺序。
-
-
继承(Inheritance)
-
公有继承(
class Derived : public Base
)的"is-a"关系。 -
虚函数与多态:
virtual
关键字的作用,动态绑定的实现原理。 -
纯虚函数与抽象类:
virtual void func() = 0;
的语义。
-
-
多态(Polymorphism)
-
虚函数表(vtable)与虚指针(vptr)的底层机制。
-
动态类型转换:
dynamic_cast
的使用场景与限制。 -
析构函数必须为虚函数的原因:避免内存泄漏。
-
class Shape {
public:
virtual void draw() const = 0; // 纯虚函数
virtual ~Shape() {} // 虚析构函数
};
class Circle : public Shape {
public:
void draw() const override {
cout << "Drawing a circle" << endl;
}
};
二、内存管理(Memory Management)
-
堆与栈的差异
-
栈:自动分配/释放,速度快,空间有限。
-
堆:手动管理(
new
/delete
),灵活但易出错。
-
-
深浅拷贝问题
-
默认拷贝构造函数与赋值运算符的浅拷贝风险。
-
实现深拷贝的示例:
class String { private: char* data; public: // 自定义拷贝构造函数 String(const String& other) { data = new char[strlen(other.data) + 1]; strcpy(data, other.data); } // 自定义赋值运算符 String& operator=(const String& other) { if (this != &other) { delete[] data; data = new char[strlen(other.data) + 1]; strcpy(data, other.data); } return *this; } };
-
-
RAII(Resource Acquisition Is Initialization)
-
资源获取即初始化,通过对象生命周期管理资源(如智能指针)。
-
三、模板与泛型编程(Templates & Generic Programming)
-
函数模板
template <typename T> T max(T a, T b) { return (a > b) ? a : b; }
-
类模板
-
特化(Specialization)与偏特化(Partial Specialization)。
template <typename T> class Vector { // 通用实现 }; template <> class Vector<bool> { // 对bool类型的特化实现 };
-
-
模板元编程(TMP)
-
编译期计算:利用模板在编译期间生成代码。
-
类型萃取(Type Traits):
std::is_integral<T>::value
的应用。
-
四、STL(Standard Template Library)
-
六大组件
-
容器(Containers)、算法(Algorithms)、迭代器(Iterators)
-
适配器(Adapters)、仿函数(Functors)、分配器(Allocators)
-
-
常用容器
-
序列容器:
vector
,list
,deque
-
关联容器:
map
(红黑树实现),unordered_map
(哈希表实现)
-
-
迭代器失效问题
-
vector
插入元素可能导致所有迭代器失效。 -
map
删除元素仅影响被删除元素的迭代器。
-
五、C++对象模型(Object Model)
-
对象内存布局
-
成员变量按声明顺序排列,受内存对齐影响。
-
虚函数表指针(vptr)的位置(通常位于对象头部)。
-
-
多重继承与虚继承
-
菱形继承问题:通过虚继承避免重复基类成员。
class A {}; class B : virtual public A {}; class C : virtual public A {}; class D : public B, public C {};
-
六、C++11/14/17新特性
-
移动语义(Move Semantics)
-
右值引用(
T&&
)与std::move()
。 -
移动构造函数与移动赋值运算符。
-
-
智能指针
-
unique_ptr
(独占所有权)、shared_ptr
(共享计数)、weak_ptr
(打破循环引用)。
-
-
Lambda表达式
auto func = [](int x) -> int { return x * 2; };
七、学习建议
-
动手实践
-
对每个知识点编写示例代码并调试观察结果(如通过gdb查看对象内存布局)。
-
-
理解底层机制
-
侯捷课程强调"知其所以然",例如虚函数表如何实现多态。
-
-
善用工具
-
使用
-fdump-class-hierarchy
(GCC)查看类层次结构。 -
通过反汇编分析编译器生成的代码。
-
#include <iostream>
#include <memory>
#include <vector>
#include <string>
#include <typeinfo>
// ==================== 图形基类与派生类 ====================
class Shape {
public:
virtual void draw() const = 0;
virtual std::unique_ptr<Shape> clone() const = 0;
virtual ~Shape() = default;
void setColor(const std::string& color) { m_color = color; }
std::string getColor() const { return m_color; }
protected:
std::string m_color = "black";
};
class Circle : public Shape {
public:
explicit Circle(double r) : radius(r) {}
void draw() const override {
std::cout << "Drawing " << m_color
<< " circle (radius=" << radius << ")\n";
}
std::unique_ptr<Shape> clone() const override {
auto cloned = std::make_unique<Circle>(*this);
cloned->setColor(m_color);
return cloned;
}
private:
double radius;
};
class Rectangle : public Shape {
public:
Rectangle(double w, double h) : width(w), height(h) {}
void draw() const override {
std::cout << "Drawing " << m_color
<< " rectangle (" << width << "x" << height << ")\n";
}
std::unique_ptr<Shape> clone() const override {
auto cloned = std::make_unique<Rectangle>(*this);
cloned->setColor(m_color);
return cloned;
}
private:
double width;
double height;
};
// ==================== 画布类 ====================
class Canvas {
public:
template<typename T, typename... Args>
void addShape(Args&&... args) {
shapes.emplace_back(
std::make_unique<T>(std::forward<Args>(args)...)
);
}
void drawAll() const {
for (const auto& shape : shapes) {
shape->draw();
}
}
Canvas clone() const {
Canvas newCanvas;
for (const auto& shape : shapes) {
newCanvas.shapes.push_back(shape->clone());
}
return newCanvas;
}
// 获取指定索引的图形对象
std::unique_ptr<Shape>& getShape(size_t index) {
return shapes[index];
}
// 获取图形容器引用
const std::vector<std::unique_ptr<Shape>>& getShapes() const {
return shapes;
}
private:
std::vector<std::unique_ptr<Shape>> shapes;
};
// ==================== 工具模板函数 ====================
template<typename Container>
void printContainerInfo(const Container& c) {
std::cout << "\nContainer Info:"
<< "\n Size: " << c.size()
<< "\n Capacity: " << c.capacity()
<< "\n Type: " << typeid(typename Container::value_type).name()
<< "\n\n";
}
template<typename T>
void transferOwnership(std::unique_ptr<T>& src, std::unique_ptr<T>& dest) {
dest = std::move(src);
}
// ==================== 主程序 ====================
int main() {
Canvas mainCanvas;
// 添加图形对象
mainCanvas.addShape<Circle>(5.0); // 圆形半径5
mainCanvas.addShape<Rectangle>(3.0, 4.0); // 矩形3x4
// 克隆画布
Canvas backupCanvas = mainCanvas.clone();
// 修改原始画布的第一个图形颜色
if (mainCanvas.getShapes().size() > 0) {
auto& firstShape = mainCanvas.getShape(0);
if (dynamic_cast<Circle*>(firstShape.get())) {
firstShape->setColor("red");
}
}
// 绘制对比
std::cout << "===== Main Canvas =====\n";
mainCanvas.drawAll();
std::cout << "\n===== Backup Canvas =====\n";
backupCanvas.drawAll();
// 演示模板函数
printContainerInfo(mainCanvas.getShapes());
// 演示移动语义
std::unique_ptr<Shape> src = std::make_unique<Circle>(2.0);
std::unique_ptr<Shape> dest;
transferOwnership(src, dest);
std::cout << "After ownership transfer:\n";
if (dest) dest->draw();
if (!src) std::cout << "Source pointer is now null\n";
return 0;
}
编译与运行说明:
保存为
main.cpp
使用支持C++17的编译器编译:
g++ -std=c++17 -o graphics main.cpp运行程序:
./graphics
输出示例:
===== Main Canvas =====
Drawing red circle (radius=5)
Drawing black rectangle (3x4)
===== Backup Canvas =====
Drawing black circle (radius=5)
Drawing black rectangle (3x4)
Container Info:
Size: 2
Capacity: 2
Type: St10unique_ptrI5ShapeSt14default_deleteIS0_EE
After ownership transfer:
Drawing black circle (radius=2)
Source pointer is now null
项目特点:
-
单一文件实现所有功能
-
包含完整的多态、模板、智能指针应用
-
演示深拷贝、移动语义等关键特性
-
可直接编译验证所有知识点
-
包含异常安全的动态类型转换检查