【学习笔记】C++面向对象编程核心技术详解
📝 说明 :本文为C++学习笔记,AI辅助系统整理
📅 整理时间 :2025年9-10月
🎯 课时 :课时02 - 面向对象编程核心
💡 目的 :深入理解C++面向对象核心机制
难度:⭐⭐⭐☆☆ | 时长:2小时 | 类型:核心必修
📚 本文内容
🎯 学习目标
通过本课时的学习,你将掌握:
- 面向对象编程的核心思想和三大特性
- 类与对象的设计原则和最佳实践
- 继承机制的原理和应用场景
- 多态的实现机制和动态绑定
- 虚函数和抽象类的设计模式
📚 核心知识体系
🔍 1. 类与对象基础
🎯 面向对象核心概念
面向对象编程 封装 Encapsulation 继承 Inheritance 多态 Polymorphism 数据隐藏 接口设计 代码复用 is-a关系 接口统一 动态绑定
💡 类的设计原则
cpp
class Student {
private:
// 数据成员(封装性:隐藏内部实现)
string name;
int age;
vector<int> scores;
public:
// 构造函数:对象创建时的初始化
Student(const string& n, int a) : name(n), age(a) {
cout << "Student对象创建:" << name << endl;
}
// 拷贝构造函数:用另一个对象初始化
Student(const Student& other) : name(other.name), age(other.age), scores(other.scores) {
cout << "Student对象拷贝:" << name << endl;
}
// 析构函数:对象销毁时的清理工作
~Student() {
cout << "Student对象销毁:" << name << endl;
}
// 成员函数:对象的行为
void addScore(int score) {
if (score >= 0 && score <= 100) {
scores.push_back(score);
} else {
throw invalid_argument("成绩必须在0-100之间");
}
}
double getAverageScore() const {
if (scores.empty()) return 0.0;
int sum = 0;
for (int score : scores) {
sum += score;
}
return static_cast<double>(sum) / scores.size();
}
// getter函数:提供只读访问
const string& getName() const { return name; }
int getAge() const { return age; }
// setter函数:提供受控修改
void setAge(int newAge) {
if (newAge > 0 && newAge < 150) {
age = newAge;
} else {
throw invalid_argument("年龄必须在合理范围内");
}
}
};
🔧 构造函数详解
cpp
class Rectangle {
private:
double width, height;
public:
// 1. 默认构造函数
Rectangle() : width(1.0), height(1.0) {
cout << "默认构造:1x1矩形" << endl;
}
// 2. 参数构造函数
Rectangle(double w, double h) : width(w), height(h) {
if (w <= 0 || h <= 0) {
throw invalid_argument("长宽必须为正数");
}
cout << "参数构造:" << w << "x" << h << "矩形" << endl;
}
// 3. 拷贝构造函数
Rectangle(const Rectangle& other) : width(other.width), height(other.height) {
cout << "拷贝构造:" << width << "x" << height << "矩形" << endl;
}
// 4. 移动构造函数(C++11)
Rectangle(Rectangle&& other) noexcept : width(other.width), height(other.height) {
other.width = other.height = 0; // 移动后源对象置空
cout << "移动构造:" << width << "x" << height << "矩形" << endl;
}
// 赋值运算符重载
Rectangle& operator=(const Rectangle& other) {
if (this != &other) { // 自赋值检查
width = other.width;
height = other.height;
}
return *this;
}
double getArea() const { return width * height; }
double getPerimeter() const { return 2 * (width + height); }
};
void demonstrateConstructors() {
Rectangle r1; // 调用默认构造函数
Rectangle r2(5, 3); // 调用参数构造函数
Rectangle r3 = r2; // 调用拷贝构造函数
Rectangle r4(move(r1)); // 调用移动构造函数
r3 = r2; // 调用赋值运算符
}
🔍 2. 继承机制深度解析
🎯 继承的层次结构设计
Animal 基类 Mammal 哺乳动物 Bird 鸟类 Fish 鱼类 Dog 狗 Cat 猫 Human 人类 Eagle 老鹰 Penguin 企鹅
💡 继承的实现和访问控制
cpp
// 基类:动物
class Animal {
protected: // protected:子类可访问,外部不可访问
string name;
int age;
private: // private:只有本类可访问
string species;
public: // public:任何地方都可访问
Animal(const string& n, int a, const string& s)
: name(n), age(a), species(s) {
cout << "Animal构造:" << name << endl;
}
virtual ~Animal() { // 虚析构函数:确保正确释放
cout << "Animal析构:" << name << endl;
}
// 虚函数:可以被子类重写
virtual void makeSound() const {
cout << name << " makes some sound" << endl;
}
virtual void move() const {
cout << name << " moves around" << endl;
}
// 非虚函数:子类继承但不能重写
void sleep() const {
cout << name << " is sleeping" << endl;
}
// getter函数
const string& getName() const { return name; }
int getAge() const { return age; }
};
// 派生类:狗
class Dog : public Animal { // public继承:保持基类的访问级别
private:
string breed; // 品种
public:
Dog(const string& n, int a, const string& b)
: Animal(n, a, "Canine"), breed(b) { // 调用基类构造函数
cout << "Dog构造:" << name << "(" << breed << ")" << endl;
}
~Dog() {
cout << "Dog析构:" << name << endl;
}
// 重写基类虚函数
void makeSound() const override {
cout << name << " barks: Woof! Woof!" << endl;
}
void move() const override {
cout << name << " runs on four legs" << endl;
}
// 新增方法
void wagTail() const {
cout << name << " wags tail happily" << endl;
}
void fetch() const {
cout << name << " fetches the ball" << endl;
}
const string& getBreed() const { return breed; }
};
// 派生类:鸟
class Bird : public Animal {
private:
double wingspan; // 翼展
public:
Bird(const string& n, int a, double ws)
: Animal(n, a, "Avian"), wingspan(ws) {
cout << "Bird构造:" << name << "(翼展" << wingspan << "cm)" << endl;
}
~Bird() {
cout << "Bird析构:" << name << endl;
}
void makeSound() const override {
cout << name << " chirps: Tweet! Tweet!" << endl;
}
void move() const override {
cout << name << " flies in the sky" << endl;
}
virtual void fly() const { // 新的虚函数
cout << name << " spreads wings and flies" << endl;
}
double getWingspan() const { return wingspan; }
};
🔧 继承中的构造和析构顺序
cpp
class Base {
public:
Base() { cout << "Base构造" << endl; }
virtual ~Base() { cout << "Base析构" << endl; }
};
class Derived : public Base {
public:
Derived() { cout << "Derived构造" << endl; }
~Derived() { cout << "Derived析构" << endl; }
};
void demonstrateOrder() {
cout << "=== 对象创建 ===" << endl;
Derived obj; // 输出:Base构造 -> Derived构造
cout << "=== 对象销毁 ===" << endl;
} // 输出:Derived析构 -> Base析构
🔍 3. 多态机制和虚函数
🎯 多态的实现原理
运行时多态 编译时多态 虚函数表 虚函数 动态绑定 模板特化 函数重载 运算符重载
💡 虚函数表机制
cpp
class Shape {
public:
virtual void draw() const = 0; // 纯虚函数
virtual double getArea() const = 0; // 纯虚函数
virtual ~Shape() = default; // 虚析构函数
// 非虚函数
void printInfo() const {
cout << "这是一个形状,面积为:" << getArea() << endl;
}
};
class Circle : public Shape {
private:
double radius;
public:
Circle(double r) : radius(r) {}
void draw() const override {
cout << "绘制圆形,半径:" << radius << endl;
}
double getArea() const override {
return 3.14159 * radius * radius;
}
};
class Rectangle : public Shape {
private:
double width, height;
public:
Rectangle(double w, double h) : width(w), height(h) {}
void draw() const override {
cout << "绘制矩形," << width << "x" << height << endl;
}
double getArea() const override {
return width * height;
}
};
// 多态的威力:统一接口处理不同对象
void processShapes(const vector<unique_ptr<Shape>>& shapes) {
for (const auto& shape : shapes) {
shape->draw(); // 动态绑定:运行时决定调用哪个版本
shape->printInfo(); // 调用基类方法,但内部会调用虚函数
cout << "---" << endl;
}
}
void demonstratePolymorphism() {
vector<unique_ptr<Shape>> shapes;
shapes.push_back(make_unique<Circle>(5.0));
shapes.push_back(make_unique<Rectangle>(4.0, 6.0));
shapes.push_back(make_unique<Circle>(3.0));
processShapes(shapes); // 统一处理不同类型的形状
}
🔧 虚函数的高级特性
cpp
class Vehicle {
public:
virtual void start() {
cout << "Vehicle启动" << endl;
}
virtual void stop() {
cout << "Vehicle停止" << endl;
}
// final关键字:禁止进一步重写
virtual void maintenance() final {
cout << "进行标准维护" << endl;
}
virtual ~Vehicle() = default;
};
class Car : public Vehicle {
public:
void start() override {
cout << "汽车点火启动" << endl;
}
void stop() override {
cout << "汽车刹车停止" << endl;
}
// void maintenance() override {} // 错误:final函数不能重写
};
class ElectricCar final : public Car { // final类:不能被继承
public:
void start() override {
cout << "电动汽车静默启动" << endl;
}
};
// class HybridCar : public ElectricCar {}; // 错误:final类不能被继承
🔍 4. 抽象类和接口设计
🎯 抽象类的设计模式
cpp
// 抽象基类:定义接口规范
class Database {
public:
// 纯虚函数:强制子类实现
virtual bool connect(const string& connectionString) = 0;
virtual void disconnect() = 0;
virtual bool execute(const string& sql) = 0;
virtual vector<string> query(const string& sql) = 0;
// 虚函数:提供默认实现,子类可选择重写
virtual void beginTransaction() {
cout << "开始事务" << endl;
}
virtual void commitTransaction() {
cout << "提交事务" << endl;
}
virtual void rollbackTransaction() {
cout << "回滚事务" << endl;
}
// 模板方法模式:定义算法骨架
bool executeWithTransaction(const string& sql) {
beginTransaction();
try {
bool result = execute(sql);
if (result) {
commitTransaction();
return true;
} else {
rollbackTransaction();
return false;
}
} catch (...) {
rollbackTransaction();
throw;
}
}
virtual ~Database() = default;
};
// MySQL实现
class MySQLDatabase : public Database {
private:
bool connected = false;
public:
bool connect(const string& connectionString) override {
cout << "连接MySQL数据库:" << connectionString << endl;
connected = true;
return true;
}
void disconnect() override {
if (connected) {
cout << "断开MySQL连接" << endl;
connected = false;
}
}
bool execute(const string& sql) override {
if (!connected) {
throw runtime_error("数据库未连接");
}
cout << "执行MySQL语句:" << sql << endl;
return true;
}
vector<string> query(const string& sql) override {
if (!connected) {
throw runtime_error("数据库未连接");
}
cout << "查询MySQL:" << sql << endl;
return {"结果1", "结果2", "结果3"};
}
// 重写事务方法(MySQL特有的实现)
void beginTransaction() override {
cout << "MySQL: START TRANSACTION" << endl;
}
};
// PostgreSQL实现
class PostgreSQLDatabase : public Database {
private:
bool connected = false;
public:
bool connect(const string& connectionString) override {
cout << "连接PostgreSQL数据库:" << connectionString << endl;
connected = true;
return true;
}
void disconnect() override {
if (connected) {
cout << "断开PostgreSQL连接" << endl;
connected = false;
}
}
bool execute(const string& sql) override {
if (!connected) {
throw runtime_error("数据库未连接");
}
cout << "执行PostgreSQL语句:" << sql << endl;
return true;
}
vector<string> query(const string& sql) override {
if (!connected) {
throw runtime_error("数据库未连接");
}
cout << "查询PostgreSQL:" << sql << endl;
return {"PG结果1", "PG结果2"};
}
};
// 数据库工厂
class DatabaseFactory {
public:
static unique_ptr<Database> createDatabase(const string& type) {
if (type == "mysql") {
return make_unique<MySQLDatabase>();
} else if (type == "postgresql") {
return make_unique<PostgreSQLDatabase>();
} else {
throw invalid_argument("不支持的数据库类型:" + type);
}
}
};
void demonstrateAbstractClass() {
auto db = DatabaseFactory::createDatabase("mysql");
db->connect("localhost:3306/test");
// 使用模板方法
db->executeWithTransaction("INSERT INTO users VALUES (1, 'Alice')");
auto results = db->query("SELECT * FROM users");
for (const auto& result : results) {
cout << "查询结果:" << result << endl;
}
db->disconnect();
}
🎯 面试高频考点总结
🔥 核心概念问答
1. 面向对象三大特性是什么?
"封装、继承、多态。
- 封装:隐藏内部实现,提供公共接口,提高安全性和模块化
- 继承:代码复用,建立is-a关系,支持层次化设计
- 多态:统一接口,动态绑定,提高代码灵活性和扩展性"
2. 虚函数的作用和实现原理?
"虚函数用于实现运行时多态。编译器为每个包含虚函数的类
创建虚函数表(vtable),对象包含指向vtable的指针。
调用虚函数时通过vtable查找实际函数地址,实现动态绑定。"
3. 抽象类和接口的区别?
"C++中没有接口关键字,通过纯虚函数实现接口。
抽象类可以包含数据成员和非纯虚函数,提供部分实现;
纯虚类(只有纯虚函数)相当于接口,只定义规范不提供实现。"
4. 什么时候使用继承?
"继承适用于:明确的is-a关系、需要代码复用、
需要多态行为的场景。但要避免过深的继承层次,
优先考虑组合而非继承(composition over inheritance)。"
🚀 设计模式应用
📝 模板方法模式
cpp
class DataProcessor {
public:
// 模板方法:定义算法骨架
void process() {
loadData();
if (validateData()) {
transformData();
saveData();
} else {
handleError();
}
}
protected:
virtual void loadData() = 0;
virtual bool validateData() = 0;
virtual void transformData() = 0;
virtual void saveData() = 0;
virtual void handleError() {
cout << "数据处理出错" << endl;
}
};
🎯 策略模式
cpp
class SortStrategy {
public:
virtual void sort(vector<int>& data) = 0;
virtual ~SortStrategy() = default;
};
class QuickSort : public SortStrategy {
public:
void sort(vector<int>& data) override {
// 快速排序实现
}
};
class Context {
private:
unique_ptr<SortStrategy> strategy;
public:
void setStrategy(unique_ptr<SortStrategy> s) {
strategy = move(s);
}
void executeSort(vector<int>& data) {
strategy->sort(data);
}
};
🎉 课时总结
通过本课时的学习,我们深入掌握了C++面向对象编程的核心:
- ✅ 类与对象:理解了封装的重要性和构造/析构的机制
- ✅ 继承机制:掌握了代码复用和is-a关系的建立
- ✅ 多态特性:理解了虚函数和动态绑定的原理
- ✅ 抽象设计:学会了如何设计接口和抽象类
- ✅ 设计模式:了解了面向对象设计的最佳实践
面向对象编程不仅仅是语法特性,更是一种设计思想。它帮助我们构建更加模块化、可维护、可扩展的软件系统。
下一课时,我们将学习C++的STL标准模板库,了解如何使用现成的高效数据结构和算法。
💡 设计原则:
- 单一职责原则:一个类只做一件事
- 开闭原则:对扩展开放,对修改封闭
- 里氏替换原则:子类可以替换父类
- 依赖倒置原则:依赖抽象而非具体实现