第9章 C++面试面向对象编程核心机制深度解析
C++面向对象编程核心机制深度解析
引言
面向对象编程(Object-Oriented Programming,OOP)是现代软件开发的核心范式,而C++作为支持面向对象编程的高效系统级语言,提供了完整且强大的面向对象特性。理解面向对象的基本原理、掌握类和对象的设计方法、熟悉多态的实现机制,对于构建可维护、可扩展的软件系统至关重要。
在软件开发实践中,面向对象编程不仅仅是一种编程技术,更是一种思维方式。它通过模拟现实世界中的实体和关系,将复杂的系统分解为相互协作的对象,从而降低系统的复杂度,提高代码的复用性和可维护性。C++在提供面向对象支持的同时,保持了与C语言的兼容性,使得开发者能够在需要时进行底层操作,这种灵活性是C++的独特优势。
本章将深入探讨面向对象编程的核心概念,系统分析类与对象的设计原理,详细讲解类成员的访问控制机制,并全面剖析多态性的实现方式。通过理论结合实践的方式,帮助读者建立完整的面向对象知识体系,掌握在C++中运用面向对象思想解决实际问题的能力。
第九章 面向对象编程范式精解
编程范式比较分析
在软件开发领域,面向对象编程和面向过程编程代表了两种不同的程序设计范式。理解这两种范式的本质区别,对于选择合适的设计方法和构建高质量的软件系统具有重要意义。
面向过程编程以过程或函数为中心,将程序看作一系列顺序执行的操作步骤。数据和处理数据的函数是分离的,程序的重点在于算法的实现和函数的调用顺序。这种范式适合解决步骤明确、流程固定的问题,但在处理复杂系统时容易出现代码冗余和维护困难。
面向对象编程则以对象为中心,将数据和对数据的操作封装在一起。对象通过消息传递进行通信,程序的设计重点在于识别系统中的实体、定义实体的属性和行为、以及建立实体之间的关系。这种范式更接近人类对现实世界的认知方式,能够更好地应对需求变化和系统复杂度增长。
面向对象的三个基本特征——封装、继承和多态,共同构成了面向对象编程的理论基础。封装隐藏了对象的内部实现细节,只暴露必要的接口;继承允许在已有类的基础上创建新类,实现代码的复用和层次的抽象;多态使得不同类的对象可以对同一消息作出不同的响应,提高了程序的灵活性和可扩展性。
下面通过具体示例来对比两种编程范式的差异:
#include <iostream>
#include <string>
#include <vector>
// 面向过程编程示例
namespace ProceduralProgramming
{
struct StudentRecord
{
std::string name;
int age;
double score;
};
void initializeStudent(StudentRecord* student, const std::string& name, int age, double score)
{
student->name = name;
student->age = age;
student->score = score;
}
void displayStudent(const StudentRecord* student)
{
std::cout << "姓名: " << student->name
<< ", 年龄: " << student->age
<< ", 成绩: " << student->score << std::endl;
}
void updateStudentScore(StudentRecord* student, double newScore)
{
student->score = newScore;
}
double calculateAverageScore(const StudentRecord students[], int count)
{
if (count == 0) return 0.0;
double total = 0.0;
for (int i = 0; i < count; ++i)
{
total += students[i].score;
}
return total / count;
}
void demonstrateProceduralApproach()
{
std::cout << "=== 面向过程编程演示 ===" << std::endl;
const int studentCount = 3;
StudentRecord students[studentCount];
initializeStudent(&students[0], "张三", 20, 85.5);
initializeStudent(&students[1], "李四", 21, 92.0);
initializeStudent(&students[2], "王五", 19, 78.5);
std::cout << "学生信息:" << std::endl;
for (int i = 0; i < studentCount; ++i)
{
displayStudent(&students[i]);
}
updateStudentScore(&students[0], 90.0);
std::cout << "\n更新后的学生信息:" << std::endl;
displayStudent(&students[0]);
double average = calculateAverageScore(students, studentCount);
std::cout << "平均成绩: " << average << std::endl;
}
}
// 面向对象编程示例
namespace ObjectOrientedProgramming
{
class Student
{
private:
std::string studentName;
int studentAge;
double studentScore;
public:
Student(const std::string& name, int age, double score)
: studentName(name), studentAge(age), studentScore(score)
{
}
void displayInfo() const
{
std::cout << "姓名: " << studentName
<< ", 年龄: " << studentAge
<< ", 成绩: " << studentScore << std::endl;
}
void updateScore(double newScore)
{
if (newScore >= 0 && newScore <= 100)
{
studentScore = newScore;
}
else
{
std::cout << "无效的成绩值: " << newScore << std::endl;
}
}
double getScore() const
{
return studentScore;
}
std::string getName() const
{
return studentName;
}
};
class GradeManager
{
private:
std::vector<Student> studentList;
public:
void addStudent(const Student& student)
{
studentList.push_back(student);
}
void displayAllStudents() const
{
std::cout << "所有学生信息:" << std::endl;
for (const auto& student : studentList)
{
student.displayInfo();
}
}
double calculateAverageScore() const
{
if (studentList.empty()) return 0.0;
double total = 0.0;
for (const auto& student : studentList)
{
total += student.getScore();
}
return total / studentList.size();
}
Student* findStudentByName(const std::string& name)
{
for (auto& student : studentList)
{
if (student.getName() == name)
{
return &student;
}
}
return nullptr;
}
};
void demonstrateObjectOrientedApproach()
{
std::cout << "\n=== 面向对象编程演示 ===" << std::endl;
GradeManager manager;
manager.addStudent(Student("张三", 20, 85.5));
manager.addStudent(Student("李四", 21, 92.0));
manager.addStudent(Student("王五", 19, 78.5));
manager.displayAllStudents();
Student* student = manager.findStudentByName("张三");
if (student)
{
student->updateScore(90.0);
std::cout << "\n更新后的学生信息:" << std::endl;
student->displayInfo();
}
double average = manager.calculateAverageScore();
std::cout << "平均成绩: " << average << std::endl;
}
}
class ProgrammingParadigmComparator
{
public:
void demonstrateParadigmDifferences()
{
std::cout << "=== 编程范式对比分析 ===" << std::endl;
ProceduralProgramming::demonstrateProceduralApproach();
ObjectOrientedProgramming::demonstrateObjectOrientedApproach();
analyzeKeyDifferences();
demonstrateOOAdvantages();
}
private:
void analyzeKeyDifferences()
{
std::cout << "\n--- 两种范式的主要区别 ---" << std::endl;
std::cout << "1. 设计中心:" << std::endl;
std::cout << " - 面向过程: 以函数为中心,关注操作步骤" << std::endl;
std::cout << " - 面向对象: 以对象为中心,关注实体和关系" << std::endl;
std::cout << "2. 数据与行为关系:" << std::endl;
std::cout << " - 面向过程: 数据和行为分离" << std::endl;
std::cout << " - 面向对象: 数据和行为封装在一起" << std::endl;
std::cout << "3. 代码复用方式:" << std::endl;
std::cout << " - 面向过程: 通过函数复用" << std::endl;
std::cout << " - 面向对象: 通过继承和组合复用" << std::endl;
std::cout << "4. 维护性:" << std::endl;
std::cout << " - 面向过程: 修改可能影响多个函数" << std::endl;
std::cout << " - 面向对象: 修改通常局限于单个类" << std::endl;
}
void demonstrateOOAdvantages()
{
std::cout << "\n--- 面向对象编程的优势 ---" << std::endl;
std::cout << "1. 封装性: 隐藏实现细节,提供清晰接口" << std::endl;
std::cout << "2. 继承性: 支持代码复用和层次化设计" << std::endl;
std::cout << "3. 多态性: 提高代码灵活性和可扩展性" << std::endl;
std::cout << "4. 模块化: 便于团队协作和系统维护" << std::endl;
std::cout << "5. 现实映射: 更符合人类思维模式" << std::endl;
demonstrateRealWorldExample();
}
void demonstrateRealWorldExample()
{
std::cout << "\n--- 现实世界问题建模 ---" << std::endl;
class BankAccount
{
private:
std::string accountNumber;
std::string accountHolder;
double balance;
public:
BankAccount(const std::string& number, const std::string& holder, double initialBalance)
: accountNumber(number), accountHolder(holder), balance(initialBalance)
{
}
void deposit(double amount)
{
if (amount > 0)
{
balance += amount;
std::cout << "存款 " << amount << " 成功,当前余额: " << balance << std::endl;
}
}
bool withdraw(double amount)
{
if (amount > 0 && amount <= balance)
{
balance -= amount;
std::cout << "取款 " << amount << " 成功,当前余额: " << balance << std::endl;
return true;
}
else
{
std::cout << "取款失败: 余额不足或金额无效" << std::endl;
return false;
}
}
void displayAccountInfo() const
{
std::cout << "账户: " << accountNumber
<< ", 持有人: " << accountHolder
<< ", 余额: " << balance << std::endl;
}
double getBalance() const { return balance; }
};
BankAccount account("123456789", "张三", 1000.0);
account.displayAccountInfo();
account.deposit(500.0);
account.withdraw(200.0);
account.withdraw(2000.0); // 应该失败
}
};
int main()
{
ProgrammingParadigmComparator comparator;
comparator.demonstrateParadigmDifferences();
return 0;
}
这个示例通过对比面向过程和面向对象两种编程范式,清晰地展示了它们的差异:
- 面向过程示例:展示了以函数为中心的设计方法,数据结构和操作函数分离。
- 面向对象示例:演示了以对象为中心的设计方法,数据和行为封装在类中。
- 范式对比:系统分析了两种范式在设计中心、数据行为关系、代码复用和维护性等方面的区别。
- 现实示例:通过银行账户类展示了面向对象建模的实际应用。
面向对象编程的核心优势在于它能够更好地应对复杂性。通过封装、继承和多态这三个基本特性,面向对象编程提供了强大的工具来构建模块化、可复用和可维护的软件系统。
类与结构体设计原理
在C++中,类和结构体都是用户自定义类型的基础构建块,它们有很多相似之处,但也存在重要的区别。理解这些区别对于做出正确的设计决策至关重要。
从语法上看,C++中的类和结构体几乎完全相同,都可以包含数据成员和成员函数,都支持继承和多态。它们的主要区别在于默认的访问控制:类的成员默认是private的,而结构体的成员默认是public的。这个看似微小的差异反映了它们不同的设计意图和使用场景。
类通常用于表示具有复杂行为和内部状态的实体,强调封装和信息隐藏。结构体则更适合表示简单的数据聚合,或者在与C语言交互时保持兼容性。在现代C++中,这种区分已经变得相对模糊,开发者可以根据团队的编码规范和具体需求来选择使用类或结构体。
抽象类作为面向对象设计中的重要概念,定义了一组接口规范而不提供完整实现。它通过纯虚函数强制派生类实现特定的功能,实现了接口与实现的分离。抽象类为系统提供了稳定的抽象层,使得具体实现的变化不会影响依赖抽象的用户代码。
下面通过详细示例来探讨类和结构体的设计原理:
#include <iostream>
#include <string>
#include <vector>
#include <memory>
class ClassDesignPrinciples
{
public:
void demonstrateClassAndStruct()
{
std::cout << "=== 类与结构体设计原理 ===" << std::endl;
demonstrateBasicDifferences();
demonstrateAccessControl();
demonstrateInheritanceDifferences();
demonstrateAbstractClasses();
}
private:
void demonstrateBasicDifferences()
{
std::cout << "\n--- 类与结构体基础区别 ---" << std::endl;
// 结构体示例 - 默认public访问
struct Point
{
// 默认public
double x;
double y;
// 成员函数
void display() const
{
std::cout << "点(" << x << ", " << y << ")" << std::endl;
}
double distanceFromOrigin() const
{
return std::sqrt(x * x + y * y);
}
};
// 类示例 - 默认private访问
class Circle
{
private:
Point center;
double radius;
public:
Circle(const Point& c, double r) : center(c), radius(r)
{
}
double getArea() const
{
return 3.14159 * radius * radius;
}
void display() const
{
std::cout << "圆形 - ";
center.display();
std::cout << "半径: " << radius << ", 面积: " << getArea() << std::endl;
}
// 访问器方法
double getRadius() const { return radius; }
void setRadius(double r)
{
if (r > 0) radius = r;
}
};
Point p{3.0, 4.0};
p.display();
std::cout << "到原点距离: " << p.distanceFromOrigin() << std::endl;
Circle c(p, 5.0);
c.display();
// 结构体成员可以直接访问
p.x = 5.0;
p.y = 12.0;
// 类成员需要通过公共接口访问
c.setRadius(10.0);
std::cout << "修改后半径: " << c.getRadius() << std::endl;
}
void demonstrateAccessControl()
{
std::cout << "\n--- 访问控制机制 ---" << std::endl;
class AccessDemo
{
private:
int privateVar;
protected:
int protectedVar;
public:
int publicVar;
AccessDemo() : privateVar(1), protectedVar(2), publicVar(3)
{
}
void demonstrateAccess()
{
std::cout << "类内访问:" << std::endl;
std::cout << "private: " << privateVar << std::endl;
std::cout << "protected: " << protectedVar << std::endl;
std::cout << "public: " << publicVar << std::endl;
}
};
class DerivedClass : public AccessDemo
{
public:
void demonstrateInheritedAccess()
{
std::cout << "派生类内访问:" << std::endl;
// std::cout << privateVar; // 错误:不能访问基类private成员
std::cout << "protected: " << protectedVar << std::endl; // 可以访问
std::cout << "public: " << publicVar << std::endl; // 可以访问
}
};
AccessDemo obj;
obj.demonstrateAccess();
std::cout << "类外访问:" << std::endl;
// std::cout << obj.privateVar; // 错误:不能访问private成员
// std::cout << obj.protectedVar; // 错误:不能访问protected成员
std::cout << "public: " << obj.publicVar << std::endl; // 可以访问
DerivedClass derived;
derived.demonstrateInheritedAccess();
}
void demonstrateInheritanceDifferences()
{
std::cout << "\n--- 继承中的区别 ---" << std::endl;
struct BaseStruct
{
int baseData;
void baseMethod()
{
std::cout << "BaseStruct方法" << std::endl;
}
};
class BaseClass
{
private:
int privateData;
protected:
int protectedData;
public:
int publicData;
BaseClass() : privateData(1), protectedData(2), publicData(3)
{
}
virtual void virtualMethod()
{
std::cout << "BaseClass虚方法" << std::endl;
}
};
// 结构体继承 - 默认public继承
struct DerivedStruct : BaseStruct
{
void derivedMethod()
{
baseData = 100; // 可以访问,因为是public继承
baseMethod();
}
};
// 类继承 - 默认private继承
class DerivedClass : BaseClass
{
public:
void derivedMethod()
{
// privateData = 1; // 错误:不能访问基类private成员
protectedData = 2; // 可以访问
publicData = 3; // 可以访问,但继承后变为private(因为是private继承)
virtualMethod();
}
};
// 显式指定继承方式
class ProperDerivedClass : public BaseClass
{
public:
void properMethod()
{
protectedData = 2; // 可以访问
publicData = 3; // 可以访问,且保持public
virtualMethod();
}
};
DerivedStruct ds;
ds.derivedMethod();
DerivedClass dc;
dc.derivedMethod();
ProperDerivedClass pdc;
pdc.properMethod();
pdc.publicData = 10; // 可以访问,因为是public继承
}
void demonstrateAbstractClasses()
{
std::cout << "\n--- 抽象类与接口设计 ---" << std::endl;
// 抽象基类 - 图形接口
class Shape
{
public:
virtual double calculateArea() const = 0;
virtual double calculatePerimeter() const = 0;
virtual void display() const = 0;
virtual std::string getType() const = 0;
virtual ~Shape()
{
std::cout << "Shape析构函数" << std::endl;
}
};
// 具体实现类 - 矩形
class Rectangle : public Shape
{
private:
double length;
double width;
public:
Rectangle(double l, double w) : length(l), width(w)
{
}
double calculateArea() const override
{
return length * width;
}
double calculatePerimeter() const override
{
return 2 * (length + width);
}
void display() const override
{
std::cout << "矩形 - 长: " << length << ", 宽: " << width
<< ", 面积: " << calculateArea()
<< ", 周长: " << calculatePerimeter() << std::endl;
}
std::string getType() const override
{
return "Rectangle";
}
};
// 具体实现类 - 圆形
class Circle : public Shape
{
private:
double radius;
public:
explicit Circle(double r) : radius(r)
{
}
double calculateArea() const override
{
return 3.14159 * radius * radius;
}
double calculatePerimeter() const override
{
return 2 * 3.14159 * radius;
}
void display() const override
{
std::cout << "圆形 - 半径: " << radius
<< ", 面积: " << calculateArea()
<< ", 周长: " << calculatePerimeter() << std::endl;
}
std::string getType() const override
{
return "Circle";
}
};
// 使用抽象类指针管理具体对象
std::vector<std::unique_ptr<Shape>> shapes;
shapes.push_back(std::make_unique<Rectangle>(4.0, 6.0));
shapes.push_back(std::make_unique<Circle>(5.0));
std::cout << "图形集合:" << std::endl;
for (const auto& shape : shapes)
{
shape->display();
std::cout << "类型: " << shape->getType() << std::endl;
}
demonstrateInterfaceSegregation();
}
void demonstrateInterfaceSegregation()
{
std::cout << "\n--- 接口隔离原则 ---" << std::endl;
// 不好的设计:庞大的接口
class BadDesign
{
public:
virtual void draw() = 0;
virtual void serialize() = 0;
virtual void networkTransfer() = 0;
};
// 好的设计:分离的接口
class Drawable
{
public:
virtual void draw() = 0;
virtual ~Drawable() = default;
};
class Serializable
{
public:
virtual void serialize() = 0;
virtual ~Serializable() = default;
};
class NetworkTransferable
{
public:
virtual void networkTransfer() = 0;
virtual ~NetworkTransferable() = default;
};
// 具体类可以选择实现需要的接口
class GraphicObject : public Drawable, public Serializable
{
public:
void draw() override
{
std::cout << "绘制图形对象" << std::endl;
}
void serialize() override
{
std::cout << "序列化图形对象" << std::endl;
}
};
GraphicObject obj;
obj.draw();
obj.serialize();
std::cout << "接口隔离使设计更灵活,避免不必要的依赖" << std::endl;
}
};
class ModernClassDesign
{
public:
void demonstrateModernFeatures()
{
std::cout << "\n=== 现代C++类设计特性 ===" << std::endl;
demonstrateRuleOfFive();
demonstrateSmartPointers();
demonstrateMoveSemantics();
}
private:
void demonstrateRuleOfFive()
{
std::cout << "\n--- 五法则(Rule of Five) ---" << std::endl;
class ResourceManager
{
private:
int* data;
size_t size;
public:
// 构造函数
explicit ResourceManager(size_t s) : size(s)
{
data = new int[size];
for (size_t i = 0; i < size; ++i)
{
data[i] = static_cast<int>(i);
}
std::cout << "构造函数: 分配 " << size << " 个元素" << std::endl;
}
// 拷贝构造函数
ResourceManager(const ResourceManager& other) : size(other.size)
{
data = new int[size];
for (size_t i = 0; i < size; ++i)
{
data[i] = other.data[i];
}
std::cout << "拷贝构造函数" << std::endl;
}
// 拷贝赋值运算符
ResourceManager& operator=(const ResourceManager& other)
{
if (this != &other)
{
delete[] data;
size = other.size;
data = new int[size];
for (size_t i = 0; i < size; ++i)
{
data[i] = other.data[i];
}
}
std::cout << "拷贝赋值运算符" << std::endl;
return *this;
}
// 移动构造函数
ResourceManager(ResourceManager&& other) noexcept
: data(other.data), size(other.size)
{
other.data = nullptr;
other.size = 0;
std::cout << "移动构造函数" << std::endl;
}
// 移动赋值运算符
ResourceManager& operator=(ResourceManager&& other) noexcept
{
if (this != &other)
{
delete[] data;
data = other.data;
size = other.size;
other.data = nullptr;
other.size = 0;
}
std::cout << "移动赋值运算符" << std::endl;
return *this;
}
// 析构函数
~ResourceManager()
{
delete[] data;
std::cout << "析构函数: 释放资源" << std::endl;
}
void display() const
{
std::cout << "资源内容: ";
for (size_t i = 0; i < size && i < 5; ++i) // 只显示前5个
{
std::cout << data[i] << " ";
}
std::cout << std::endl;
}
};
ResourceManager rm1(10);
rm1.display();
ResourceManager rm2 = rm1; // 拷贝构造
rm2.display();
ResourceManager rm3(5);
rm3 = rm1; // 拷贝赋值
rm3.display();
ResourceManager rm4 = std::move(rm1); // 移动构造
rm4.display();
ResourceManager rm5(3);
rm5 = std::move(rm2); // 移动赋值
rm5.display();
}
void demonstrateSmartPointers()
{
std::cout << "\n--- 智能指针在类设计中的应用 ---" << std::endl;
class Node
{
private:
int value;
std::unique_ptr<Node> next;
public:
explicit Node(int val) : value(val), next(nullptr)
{
}
void setNext(std::unique_ptr<Node> nextNode)
{
next = std::move(nextNode);
}
void displayList() const
{
const Node* current = this;
while (current != nullptr)
{
std::cout << current->value;
if (current->next != nullptr)
{
std::cout << " -> ";
}
current = current->next.get();
}
std::cout << std::endl;
}
};
auto head = std::make_unique<Node>(1);
auto second = std::make_unique<Node>(2);
auto third = std::make_unique<Node>(3);
head->setNext(std::move(second));
head->setNext(std::move(third)); // 注意:这会断开之前的节点
head->displayList();
std::cout << "智能指针自动管理内存,避免内存泄漏" << std::endl;
}
void demonstrateMoveSemantics()
{
std::cout << "\n--- 移动语义优化 ---" << std::endl;
class StringContainer
{
private:
std::string data;
public:
StringContainer(const std::string& str) : data(str)
{
std::cout << "构造函数: " << data << std::endl;
}
StringContainer(const StringContainer& other) : data(other.data)
{
std::cout << "拷贝构造函数: " << data << std::endl;
}
StringContainer(StringContainer&& other) noexcept : data(std::move(other.data))
{
std::cout << "移动构造函数: " << data << std::endl;
}
StringContainer& operator=(StringContainer&& other) noexcept
{
if (this != &other)
{
data = std::move(other.data);
}
std::cout << "移动赋值运算符: " << data << std::endl;
return *this;
}
const std::string& getData() const { return data; }
};
StringContainer sc1("Hello");
StringContainer sc2 = std::move(sc1); // 移动构造
StringContainer sc3("World");
sc3 = std::move(sc2); // 移动赋值
std::cout << "移动语义避免了不必要的拷贝,提高性能" << std::endl;
}
};
int main()
{
ClassDesignPrinciples design;
design.demonstrateClassAndStruct();
ModernClassDesign modern;
modern.demonstrateModernFeatures();
return 0;
}
这个示例深入探讨了类和结构体的设计原理:
- 基础区别:展示了类和结构体在默认访问控制上的差异。
- 访问控制:详细说明了private、protected和public访问修饰符的作用范围。
- 继承差异:分析了在继承关系中类和结构体的不同行为。
- 抽象类:通过图形接口示例展示了抽象类的设计和应用。
ModernClassDesign类展示了现代C++中的类设计特性:
- 五法则:演示了拷贝控制成员的正确实现。
- 智能指针:展示了在类设计中使用智能指针管理资源。
- 移动语义:通过移动构造函数和移动赋值运算符优化性能。
理解这些设计原理对于创建健壮、高效的C++类至关重要。良好的类设计应该遵循面向对象的原则,提供适当的封装,支持合理的继承和多态,同时利用现代C++特性来优化性能和资源管理。
第十章 类成员访问与控制机制
成员访问方式详解
在C++面向对象编程中,类成员的正确访问是保证封装性和安全性的基础。类成员包括数据成员和成员函数,它们的访问方式直接影响到类的接口设计和内部实现的隐藏程度。
数据成员的访问应该通过精心设计的公共接口来进行,而不是直接暴露给外部。这被称为"访问器方法"模式,通过getter和setter方法来控制对数据成员的访问。这种方式可以在访问时添加验证逻辑,保持内部状态的一致性,同时在需要时改变内部实现而不影响外部代码。
成员函数的访问控制决定了哪些函数可以被外部调用,哪些只能在类内部使用。公共成员函数构成类的接口, protected成员函数供派生类使用,private成员函数则是内部实现细节。合理划分成员函数的访问级别是良好类设计的关键。
静态成员属于类本身而不是类的实例,它们在所有对象间共享。静态数据成员用于存储类级别的信息,静态成员函数可以在不创建对象的情况下调用。理解静态成员的特性和使用场景对于设计工具类和管理器类非常重要。
下面通过综合示例来详细讲解类成员的访问与控制机制:
#include <iostream>
#include <string>
#include <vector>
#include <memory>
class MemberAccessAnalysis
{
public:
void demonstrateMemberAccess()
{
std::cout << "=== 类成员访问与控制机制 ===" << std::endl;
demonstrateDataMembers();
demonstrateMemberFunctions();
demonstrateStaticMembers();
demonstrateFriendMechanism();
}
private:
void demonstrateDataMembers()
{
std::cout << "\n--- 数据成员访问控制 ---" << std::endl;
class BankAccount
{
private:
std::string accountNumber;
double balance;
std::string ownerName;
public:
BankAccount(const std::string& number, const std::string& owner, double initialBalance)
: accountNumber(number), ownerName(owner), balance(initialBalance)
{
}
// Getter方法 - 提供只读访问
std::string getAccountNumber() const
{
return accountNumber;
}
std::string getOwnerName() const
{
return ownerName;
}
double getBalance() const
{
return balance;
}
// Setter方法 - 提供受控的写访问
void setOwnerName(const std::string& newName)
{
if (!newName.empty())
{
ownerName = newName;
}
}
// 业务方法 - 封装复杂的操作逻辑
bool deposit(double amount)
{
if (amount > 0)
{
balance += amount;
std::cout << "存款 " << amount << " 成功" << std::endl;
return true;
}
return false;
}
bool withdraw(double amount)
{
if (amount > 0 && amount <= balance)
{
balance -= amount;
std::cout << "取款 " << amount << " 成功" << std::endl;
return true;
}
std::cout << "取款失败: 余额不足" << std::endl;
return false;
}
void displayAccountInfo() const
{
std::cout << "账户: " << accountNumber
<< ", 持有人: " << ownerName
<< ", 余额: " << balance << std::endl;
}
};
BankAccount account("123456", "张三", 1000.0);
account.displayAccountInfo();
// 通过公共接口访问,而不是直接访问数据成员
account.deposit(500.0);
account.withdraw(200.0);
account.setOwnerName("张四");
std::cout << "修改后信息:" << std::endl;
account.displayAccountInfo();
// 以下代码会导致编译错误,因为数据成员是private的
// account.balance = 1000000; // 错误!
// std::cout << account.accountNumber; // 错误!
}
void demonstrateMemberFunctions()
{
std::cout << "\n--- 成员函数访问控制 ---" << std::endl;
class DocumentProcessor
{
private:
std::string content;
// private辅助函数 - 内部实现细节
void normalizeContent()
{
// 移除多余空格等预处理
std::cout << "标准化文档内容" << std::endl;
}
void logOperation(const std::string& operation) const
{
std::cout << "操作日志: " << operation << std::endl;
}
protected:
// protected函数 - 供派生类使用
virtual void preProcess()
{
std::cout << "文档预处理" << std::endl;
normalizeContent();
}
virtual void postProcess()
{
std::cout << "文档后处理" << std::endl;
}
public:
void setContent(const std::string& newContent)
{
content = newContent;
logOperation("设置内容");
}
const std::string& getContent() const
{
return content;
}
// 公共接口
virtual void processDocument()
{
logOperation("开始处理文档");
preProcess();
std::cout << "处理主要内容: " << content << std::endl;
postProcess();
logOperation("文档处理完成");
}
};
class AdvancedDocumentProcessor : public DocumentProcessor
{
protected:
void preProcess() override
{
std::cout << "高级预处理" << std::endl;
DocumentProcessor::preProcess(); // 调用基类实现
}
void postProcess() override
{
std::cout << "高级后处理" << std::endl;
DocumentProcessor::postProcess(); // 调用基类实现
}
public:
void processDocument() override
{
std::cout << "=== 高级文档处理 ===" << std::endl;
DocumentProcessor::processDocument();
}
};
AdvancedDocumentProcessor processor;
processor.setContent("示例文档内容");
processor.processDocument();
}
void demonstrateStaticMembers()
{
std::cout << "\n--- 静态成员详解 ---" << std::endl;
class Employee
{
private:
std::string name;
int employeeId;
double salary;
// 静态数据成员 - 类级别信息
static int totalEmployeeCount;
static int nextEmployeeId;
public:
Employee(const std::string& empName, double empSalary)
: name(empName), salary(empSalary), employeeId(nextEmployeeId++)
{
totalEmployeeCount++;
std::cout << "创建员工: " << name << " (ID: " << employeeId
<< "), 总员工数: " << totalEmployeeCount << std::endl;
}
~Employee()
{
totalEmployeeCount--;
std::cout << "删除员工: " << name << ", 剩余员工数: " << totalEmployeeCount << std::endl;
}
// 静态成员函数 - 类级别操作
static int getTotalEmployeeCount()
{
return totalEmployeeCount;
}
static int getNextEmployeeId()
{
return nextEmployeeId;
}
// 静态工具函数
static bool isValidSalary(double salary)
{
return salary >= 0;
}
static double calculateAnnualSalary(double monthlySalary)
{
return monthlySalary * 12;
}
// 实例成员函数
void displayInfo() const
{
std::cout << "员工ID: " << employeeId
<< ", 姓名: " << name
<< ", 月薪: " << salary
<< ", 年薪: " << calculateAnnualSalary(salary) << std::endl;
}
void setSalary(double newSalary)
{
if (isValidSalary(newSalary))
{
salary = newSalary;
}
}
};
// 静态成员定义
int Employee::totalEmployeeCount = 0;
int Employee::nextEmployeeId = 1001;
std::cout << "初始员工数: " << Employee::getTotalEmployeeCount() << std::endl;
std::cout << "下一个员工ID: " << Employee::getNextEmployeeId() << std::endl;
Employee emp1("张三", 5000.0);
Employee emp2("李四", 6000.0);
emp1.displayInfo();
emp2.displayInfo();
std::cout << "当前员工数: " << Employee::getTotalEmployeeCount() << std::endl;
std::cout << "下一个员工ID: " << Employee::getNextEmployeeId() << std::endl;
// 使用静态工具函数
std::cout << "验证薪水 5000: " << Employee::isValidSalary(5000) << std::endl;
std::cout << "验证薪水 -1000: " << Employee::isValidSalary(-1000) << std::endl;
std::cout << "月薪8000的年薪: " << Employee::calculateAnnualSalary(8000) << std::endl;
{
Employee emp3("王五", 7000.0);
std::cout << "块内员工数: " << Employee::getTotalEmployeeCount() << std::endl;
}
std::cout << "块后员工数: " << Employee::getTotalEmployeeCount() << std::endl;
}
void demonstrateFriendMechanism()
{
std::cout << "\n--- 友元机制 ---" << std::endl;
class Vector3D;
class Matrix3x3
{
private:
double data[3][3];
public:
Matrix3x3()
{
for (int i = 0; i < 3; ++i)
{
for (int j = 0; j < 3; ++j)
{
data[i][j] = (i == j) ? 1.0 : 0.0; // 单位矩阵
}
}
}
explicit Matrix3x3(double values[3][3])
{
for (int i = 0; i < 3; ++i)
{
for (int j = 0; j < 3; ++j)
{
data[i][j] = values[i][j];
}
}
}
// 友元函数声明
friend Vector3D operator*(const Matrix3x3& matrix, const Vector3D& vector);
friend std::ostream& operator<<(std::ostream& os, const Matrix3x3& matrix);
void display() const
{
std::cout << "矩阵:" << std::endl;
for (int i = 0; i < 3; ++i)
{
for (int j = 0; j < 3; ++j)
{
std::cout << data[i][j] << "\t";
}
std::cout << std::endl;
}
}
};
class Vector3D
{
private:
double x, y, z;
public:
Vector3D(double xVal, double yVal, double zVal) : x(xVal), y(yVal), z(zVal)
{
}
// 友元函数声明
friend Vector3D operator*(const Matrix3x3& matrix, const Vector3D& vector);
friend std::ostream& operator<<(std::ostream& os, const Vector3D& vector);
void display() const
{
std::cout << "向量: (" << x << ", " << y << ", " << z << ")" << std::endl;
}
};
// 友元函数定义 - 可以访问两个类的私有成员
Vector3D operator*(const Matrix3x3& matrix, const Vector3D& vector)
{
double resultX = matrix.data[0][0] * vector.x + matrix.data[0][1] * vector.y + matrix.data[0][2] * vector.z;
double resultY = matrix.data[1][0] * vector.x + matrix.data[1][1] * vector.y + matrix.data[1][2] * vector.z;
double resultZ = matrix.data[2][0] * vector.x + matrix.data[2][1] * vector.y + matrix.data[2][2] * vector.z;
return Vector3D(resultX, resultY, resultZ);
}
std::ostream& operator<<(std::ostream& os, const Matrix3x3& matrix)
{
os << "Matrix3x3:" << std::endl;
for (int i = 0; i < 3; ++i)
{
for (int j = 0; j < 3; ++j)
{
os << matrix.data[i][j] << "\t";
}
os << std::endl;
}
return os;
}
std::ostream& operator<<(std::ostream& os, const Vector3D& vector)
{
os << "Vector3D(" << vector.x << ", " << vector.y << ", " << vector.z << ")";
return os;
}
// 测试友元机制
double values[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
Matrix3x3 matrix(values);
Vector3D vector(1, 2, 3);
std::cout << matrix;
std::cout << vector << std::endl;
Vector3D result = matrix * vector;
std::cout << "矩阵向量乘法结果: " << result << std::endl;
demonstrateFriendClass();
}
void demonstrateFriendClass()
{
std::cout << "\n--- 友元类 ---" << std::endl;
class SensorData
{
private:
double rawData[10];
bool calibrated;
public:
SensorData()
{
for (int i = 0; i < 10; ++i)
{
rawData[i] = i * 1.5;
}
calibrated = false;
}
// 友元类声明
friend class DataProcessor;
void displayRawData() const
{
std::cout << "原始数据: ";
for (int i = 0; i < 10; ++i)
{
std::cout << rawData[i] << " ";
}
std::cout << std::endl;
}
};
class DataProcessor
{
public:
static void calibrateData(SensorData& sensor)
{
if (!sensor.calibrated)
{
for (int i = 0; i < 10; ++i)
{
sensor.rawData[i] *= 0.95; // 校准系数
}
sensor.calibrated = true;
std::cout << "数据校准完成" << std::endl;
}
}
static double calculateAverage(const SensorData& sensor)
{
double sum = 0.0;
for (int i = 0; i < 10; ++i)
{
sum += sensor.rawData[i];
}
return sum / 10;
}
};
SensorData data;
data.displayRawData();
DataProcessor::calibrateData(data);
data.displayRawData();
double average = DataProcessor::calculateAverage(data);
std::cout << "数据平均值: " << average << std::endl;
}
};
class AccessControlBestPractices
{
public:
void demonstrateBestPractices()
{
std::cout << "\n=== 访问控制最佳实践 ===" << std::endl;
demonstrateEncapsulationBenefits();
demonstrateInterfaceDesign();
demonstrateConstCorrectness();
}
private:
void demonstrateEncapsulationBenefits()
{
std::cout << "\n--- 封装的优势 ---" << std::endl;
class TemperatureSensor
{
private:
double currentTemperature;
double minTemperature;
double maxTemperature;
bool isValidTemperature(double temp) const
{
return temp >= -50.0 && temp <= 150.0;
}
public:
TemperatureSensor() : currentTemperature(20.0), minTemperature(20.0), maxTemperature(20.0)
{
}
bool updateTemperature(double newTemp)
{
if (isValidTemperature(newTemp))
{
currentTemperature = newTemp;
if (newTemp < minTemperature) minTemperature = newTemp;
if (newTemp > maxTemperature) maxTemperature = newTemp;
return true;
}
return false;
}
double getCurrentTemperature() const { return currentTemperature; }
double getMinTemperature() const { return minTemperature; }
double getMaxTemperature() const { return maxTemperature; }
void resetStatistics()
{
minTemperature = currentTemperature;
maxTemperature = currentTemperature;
}
void displayStatus() const
{
std::cout << "当前温度: " << currentTemperature
<< "°C, 最低: " << minTemperature
<< "°C, 最高: " << maxTemperature << "°C" << std::endl;
}
};
TemperatureSensor sensor;
sensor.displayStatus();
sensor.updateTemperature(25.5);
sensor.updateTemperature(18.0);
sensor.updateTemperature(30.0);
sensor.updateTemperature(200.0); // 无效温度,不会被接受
sensor.displayStatus();
sensor.resetStatistics();
std::cout << "重置统计后:" << std::endl;
sensor.displayStatus();
std::cout << "封装确保了数据的完整性和一致性" << std::endl;
}
void demonstrateInterfaceDesign()
{
std::cout << "\n--- 接口设计原则 ---" << std::endl;
class Document
{
private:
std::string content;
std::string author;
time_t createdTime;
time_t modifiedTime;
bool isLocked;
void updateModifiedTime()
{
if (!isLocked)
{
modifiedTime = time(nullptr);
}
}
public:
Document(const std::string& initialContent, const std::string& docAuthor)
: content(initialContent), author(docAuthor), isLocked(false)
{
createdTime = time(nullptr);
modifiedTime = createdTime;
}
// 查询接口 - const成员函数
const std::string& getContent() const { return content; }
const std::string& getAuthor() const { return author; }
time_t getCreatedTime() const { return createdTime; }
time_t getModifiedTime() const { return modifiedTime; }
bool getLockStatus() const { return isLocked; }
// 命令接口 - 非const成员函数
void setContent(const std::string& newContent)
{
if (!isLocked)
{
content = newContent;
updateModifiedTime();
}
}
void setAuthor(const std::string& newAuthor)
{
if (!isLocked)
{
author = newAuthor;
updateModifiedTime();
}
}
void lockDocument() { isLocked = true; }
void unlockDocument() { isLocked = false; }
void displayInfo() const
{
std::cout << "文档信息:" << std::endl;
std::cout << "作者: " << author << std::endl;
std::cout << "创建时间: " << ctime(&createdTime);
std::cout << "修改时间: " << ctime(&modifiedTime);
std::cout << "锁定状态: " << (isLocked ? "已锁定" : "未锁定") << std::endl;
std::cout << "内容预览: "
<< (content.length() > 50 ? content.substr(0, 50) + "..." : content)
<< std::endl;
}
};
Document doc("这是一个重要的文档内容,包含了很多有价值的信息。", "张三");
doc.displayInfo();
doc.setContent("更新后的文档内容,包含了最新的信息。");
doc.lockDocument();
doc.setAuthor("李四"); // 不会生效,因为文档已锁定
std::cout << "\n修改并锁定后:" << std::endl;
doc.displayInfo();
std::cout << "良好的接口设计提供了清晰的使用契约" << std::endl;
}
void demonstrateConstCorrectness()
{
std::cout << "\n--- const正确性 ---" << std::endl;
class ConfigurationManager
{
private:
mutable int accessCount; // mutable可以在const函数中修改
std::string configData;
public:
ConfigurationManager() : accessCount(0), configData("默认配置")
{
}
// const成员函数 - 承诺不修改对象状态
const std::string& getConfigData() const
{
accessCount++; // 允许修改mutable成员
return configData;
}
int getAccessCount() const
{
return accessCount;
}
// 非const成员函数 - 可能修改对象状态
void setConfigData(const std::string& newData)
{
configData = newData;
}
void displayConfig() const
{
std::cout << "配置数据: " << configData << std::endl;
std::cout << "访问次数: " << accessCount << std::endl;
}
};
ConfigurationManager config;
const ConfigurationManager& constConfig = config;
// const对象只能调用const成员函数
constConfig.getConfigData();
constConfig.displayConfig();
// constConfig.setConfigData("新配置"); // 错误:const对象不能调用非const函数
// 非const对象可以调用所有成员函数
config.setConfigData("新配置数据");
config.displayConfig();
std::cout << "const正确性提高了代码的安全性和可读性" << std::endl;
}
};
int main()
{
MemberAccessAnalysis analysis;
analysis.demonstrateMemberAccess();
AccessControlBestPractices bestPractices;
bestPractices.demonstrateBestPractices();
return 0;
}
这个示例全面讲解了类成员的访问与控制机制:
- 数据成员访问:展示了通过getter和setter方法控制数据访问的最佳实践。
- 成员函数访问:说明了不同访问级别成员函数的设计意图和使用场景。
- 静态成员:详细讲解了静态数据成员和静态成员函数的特性和应用。
- 友元机制:演示了友元函数和友元类在特定场景下的使用。
AccessControlBestPractices类总结了访问控制的最佳实践:
- 封装优势:通过温度传感器示例展示了封装如何保证数据完整性。
- 接口设计:说明了良好接口设计的原则和重要性。
- const正确性:强调了在适当位置使用const的重要性。
正确的访问控制设计是构建健壮、可维护的面向对象系统的关键。它确保了类的内部实现可以被安全地修改,而不会影响使用该类的客户端代码。
第十一章 多态机制实现与应用
多态性原理深度解析
多态是面向对象编程的三大特征之一,它允许不同类的对象对同一消息作出不同的响应。多态性极大地提高了代码的灵活性和可扩展性,是设计模式和应用框架的基础。
在C++中,多态主要通过虚函数机制实现。当基类的指针或引用指向派生类对象时,通过虚函数表(vtable)在运行时确定应该调用哪个类的函数实现。这种运行时多态使得程序能够根据实际对象类型动态选择适当的行为,而不是在编译时静态绑定。
多态的实现依赖于几个关键机制:虚函数声明、虚函数表、虚函数表指针和动态绑定。理解这些底层机制对于正确使用多态和诊断相关问题非常重要。虚函数表为每个包含虚函数的类存储函数指针,而每个对象包含一个指向相应虚函数表的指针。
多态在软件设计中有着广泛的应用,包括接口设计、插件系统、回调机制等。通过多态,可以创建高度可扩展的系统,其中新的功能可以通过添加新的派生类来实现,而不需要修改现有的代码。
下面通过详细示例来深入解析多态的实现原理和应用:
#include <iostream>
#include <vector>
#include <memory>
#include <typeinfo>
class PolymorphismDeepDive
{
public:
void demonstratePolymorphism()
{
std::cout << "=== 多态性原理深度解析 ===" << std::endl;
demonstrateBasicPolymorphism();
demonstrateVTableMechanism();
demonstratePureVirtualFunctions();
demonstratePolymorphicContainers();
demonstrateRealWorldExample();
}
private:
void demonstrateBasicPolymorphism()
{
std::cout << "\n--- 基础多态演示 ---" << std::endl;
class Animal
{
public:
virtual void makeSound() const
{
std::cout << "动物发出声音" << std::endl;
}
virtual void move() const
{
std::cout << "动物在移动" << std::endl;
}
virtual ~Animal()
{
std::cout << "Animal析构函数" << std::endl;
}
};
class Dog : public Animal
{
public:
void makeSound() const override
{
std::cout << "汪汪!" << std::endl;
}
void move() const override
{
std::cout << "狗在跑" << std::endl;
}
~Dog() override
{
std::cout << "Dog析构函数" << std::endl;
}
};
class Cat : public Animal
{
public:
void makeSound() const override
{
std::cout << "喵喵!" << std::endl;
}
void move() const override
{
std::cout << "猫在悄悄走" << std::endl;
}
void climbTree() const
{
std::cout << "猫在爬树" << std::endl;
}
~Cat() override
{
std::cout << "Cat析构函数" << std::endl;
}
};
class Bird : public Animal
{
public:
void makeSound() const override
{
std::cout << "叽叽喳喳!" << std::endl;
}
void move() const override
{
std::cout << "鸟在飞" << std::endl;
}
~Bird() override
{
std::cout << "Bird析构函数" << std::endl;
}
};
// 使用基类指针管理派生类对象
Animal* animals[] = {new Dog(), new Cat(), new Bird()};
std::cout << "多态行为演示:" << std::endl;
for (int i = 0; i < 3; ++i)
{
animals[i]->makeSound();
animals[i]->move();
std::cout << "实际类型: " << typeid(*animals[i]).name() << std::endl;
std::cout << "---" << std::endl;
}
// 清理内存
for (int i = 0; i < 3; ++i)
{
delete animals[i];
}
demonstratePolymorphismWithReferences();
}
void demonstratePolymorphismWithReferences()
{
std::cout << "\n--- 引用多态演示 ---" << std::endl;
class Shape
{
public:
virtual double area() const = 0;
virtual void draw() const = 0;
virtual ~Shape() = default;
};
class Circle : public Shape
{
private:
double radius;
public:
explicit Circle(double r) : radius(r) {}
double area() const override
{
return 3.14159 * radius * radius;
}
void draw() const override
{
std::cout << "绘制圆形,半径: " << radius << std::endl;
}
};
class Rectangle : public Shape
{
private:
double width, height;
public:
Rectangle(double w, double h) : width(w), height(h) {}
double area() const override
{
return width * height;
}
void draw() const override
{
std::cout << "绘制矩形,宽: " << width << ", 高: " << height << std::endl;
}
};
Circle circle(5.0);
Rectangle rectangle(4.0, 6.0);
// 使用基类引用
Shape& shape1 = circle;
Shape& shape2 = rectangle;
shape1.draw();
std::cout << "面积: " << shape1.area() << std::endl;
shape2.draw();
std::cout << "面积: " << shape2.area() << std::endl;
}
void demonstrateVTableMechanism()
{
std::cout << "\n--- 虚函数表机制 ---" << std::endl;
class Base
{
public:
virtual void func1()
{
std::cout << "Base::func1" << std::endl;
}
virtual void func2()
{
std::cout << "Base::func2" << std::endl;
}
void nonVirtual()
{
std::cout << "Base::nonVirtual" << std::endl;
}
};
class Derived : public Base
{
public:
void func1() override
{
std::cout << "Derived::func1" << std::endl;
}
void func2() override
{
std::cout << "Derived::func2" << std::endl;
}
void derivedOnly()
{
std::cout << "Derived::derivedOnly" << std::endl;
}
};
Base base;
Derived derived;
std::cout << "Base对象大小: " << sizeof(base) << " 字节" << std::endl;
std::cout << "Derived对象大小: " << sizeof(derived) << " 字节" << std::endl;
std::cout << "大小差异来自虚函数表指针" << std::endl;
Base* basePtr = &derived;
basePtr->func1(); // 动态绑定 - 调用Derived::func1
basePtr->func2(); // 动态绑定 - 调用Derived::func2
basePtr->nonVirtual(); // 静态绑定 - 调用Base::nonVirtual
// basePtr->derivedOnly(); // 错误:Base类没有derivedOnly方法
demonstrateVirtualDestructor();
}
void demonstrateVirtualDestructor()
{
std::cout << "\n--- 虚析构函数的重要性 ---" << std::endl;
class BaseWithoutVirtual
{
public:
~BaseWithoutVirtual()
{
std::cout << "BaseWithoutVirtual析构函数" << std::endl;
}
};
class DerivedWithoutVirtual : public BaseWithoutVirtual
{
public:
~DerivedWithoutVirtual()
{
std::cout << "DerivedWithoutVirtual析构函数" << std::endl;
}
};
class BaseWithVirtual
{
public:
virtual ~BaseWithVirtual()
{
std::cout << "BaseWithVirtual析构函数" << std::endl;
}
};
class DerivedWithVirtual : public BaseWithVirtual
{
public:
~DerivedWithVirtual() override
{
std::cout << "DerivedWithVirtual析构函数" << std::endl;
}
};
std::cout << "无虚析构函数的情况:" << std::endl;
BaseWithoutVirtual* badPtr = new DerivedWithoutVirtual();
delete badPtr; // 只调用基类析构函数!
std::cout << "\n有虚析构函数的情况:" << std::endl;
BaseWithVirtual* goodPtr = new DerivedWithVirtual();
delete goodPtr; // 正确调用所有析构函数
}
void demonstratePureVirtualFunctions()
{
std::cout << "\n--- 纯虚函数与抽象类 ---" << std::endl;
class DatabaseConnection
{
public:
virtual void connect() = 0;
virtual void disconnect() = 0;
virtual void executeQuery(const std::string& query) = 0;
virtual bool isConnected() const = 0;
virtual ~DatabaseConnection() = default;
};
class MySQLConnection : public DatabaseConnection
{
private:
bool connected;
public:
MySQLConnection() : connected(false) {}
void connect() override
{
std::cout << "连接到MySQL数据库" << std::endl;
connected = true;
}
void disconnect() override
{
std::cout << "断开MySQL数据库连接" << std::endl;
connected = false;
}
void executeQuery(const std::string& query) override
{
if (isConnected())
{
std::cout << "执行MySQL查询: " << query << std::endl;
}
else
{
std::cout << "错误:数据库未连接" << std::endl;
}
}
bool isConnected() const override
{
return connected;
}
};
class PostgreSQLConnection : public DatabaseConnection
{
private:
bool connected;
public:
PostgreSQLConnection() : connected(false) {}
void connect() override
{
std::cout << "连接到PostgreSQL数据库" << std::endl;
connected = true;
}
void disconnect() override
{
std::cout << "断开PostgreSQL数据库连接" << std::endl;
connected = false;
}
void executeQuery(const std::string& query) override
{
if (isConnected())
{
std::cout << "执行PostgreSQL查询: " << query << std::endl;
}
else
{
std::cout << "错误:数据库未连接" << std::endl;
}
}
bool isConnected() const override
{
return connected;
}
};
// 使用抽象类接口
DatabaseConnection* db1 = new MySQLConnection();
DatabaseConnection* db2 = new PostgreSQLConnection();
db1->connect();
db1->executeQuery("SELECT * FROM users");
db1->disconnect();
db2->connect();
db2->executeQuery("SELECT * FROM products");
db2->disconnect();
delete db1;
delete db2;
// DatabaseConnection conn; // 错误:不能实例化抽象类
}
void demonstratePolymorphicContainers()
{
std::cout << "\n--- 多态容器 ---" << std::endl;
class Employee
{
protected:
std::string name;
double baseSalary;
public:
Employee(const std::string& empName, double salary)
: name(empName), baseSalary(salary)
{
}
virtual double calculateSalary() const
{
return baseSalary;
}
virtual void displayInfo() const
{
std::cout << "员工: " << name << ", 基本工资: " << baseSalary;
}
virtual ~Employee() = default;
};
class Manager : public Employee
{
private:
double bonus;
public:
Manager(const std::string& name, double salary, double mgrBonus)
: Employee(name, salary), bonus(mgrBonus)
{
}
double calculateSalary() const override
{
return baseSalary + bonus;
}
void displayInfo() const override
{
Employee::displayInfo();
std::cout << ", 奖金: " << bonus << ", 总工资: " << calculateSalary() << std::endl;
}
};
class Developer : public Employee
{
private:
int overtimeHours;
double overtimeRate;
public:
Developer(const std::string& name, double salary, int hours, double rate)
: Employee(name, salary), overtimeHours(hours), overtimeRate(rate)
{
}
double calculateSalary() const override
{
return baseSalary + (overtimeHours * overtimeRate);
}
void displayInfo() const override
{
Employee::displayInfo();
std::cout << ", 加班时间: " << overtimeHours
<< ", 总工资: " << calculateSalary() << std::endl;
}
};
// 使用智能指针管理多态对象
std::vector<std::unique_ptr<Employee>> employees;
employees.push_back(std::make_unique<Employee>("普通员工", 5000.0));
employees.push_back(std::make_unique<Manager>("张经理", 8000.0, 3000.0));
employees.push_back(std::make_unique<Developer>("李开发", 6000.0, 10, 200.0));
std::cout << "员工薪资计算:" << std::endl;
double totalSalary = 0.0;
for (const auto& emp : employees)
{
emp->displayInfo();
totalSalary += emp->calculateSalary();
}
std::cout << "总工资支出: " << totalSalary << std::endl;
}
void demonstrateRealWorldExample()
{
std::cout << "\n--- 现实世界应用示例 ---" << std::endl;
class PaymentMethod
{
public:
virtual bool processPayment(double amount) = 0;
virtual std::string getMethodName() const = 0;
virtual ~PaymentMethod() = default;
};
class CreditCardPayment : public PaymentMethod
{
private:
std::string cardNumber;
std::string expiryDate;
public:
CreditCardPayment(const std::string& number, const std::string& expiry)
: cardNumber(number), expiryDate(expiry)
{
}
bool processPayment(double amount) override
{
std::cout << "处理信用卡支付: " << amount << "元" << std::endl;
std::cout << "卡号: " << maskCardNumber() << std::endl;
// 模拟支付处理
return true;
}
std::string getMethodName() const override
{
return "信用卡支付";
}
private:
std::string maskCardNumber() const
{
if (cardNumber.length() < 4) return "****";
return "****-****-****-" + cardNumber.substr(cardNumber.length() - 4);
}
};
class PayPalPayment : public PaymentMethod
{
private:
std::string email;
public:
explicit PayPalPayment(const std::string& userEmail) : email(userEmail)
{
}
bool processPayment(double amount) override
{
std::cout << "处理PayPal支付: " << amount << "元" << std::endl;
std::cout << "PayPal账户: " << email << std::endl;
// 模拟支付处理
return true;
}
std::string getMethodName() const override
{
return "PayPal支付";
}
};
class BankTransferPayment : public PaymentMethod
{
private:
std::string accountNumber;
std::string bankName;
public:
BankTransferPayment(const std::string& accNumber, const std::string& bank)
: accountNumber(accNumber), bankName(bank)
{
}
bool processPayment(double amount) override
{
std::cout << "处理银行转账: " << amount << "元" << std::endl;
std::cout << "银行: " << bankName << ", 账户: " << accountNumber << std::endl;
// 模拟支付处理
return true;
}
std::string getMethodName() const override
{
return "银行转账";
}
};
class PaymentProcessor
{
private:
std::vector<std::unique_ptr<PaymentMethod>> availableMethods;
public:
void addPaymentMethod(std::unique_ptr<PaymentMethod> method)
{
availableMethods.push_back(std::move(method));
}
void displayAvailableMethods() const
{
std::cout << "可用支付方式:" << std::endl;
for (size_t i = 0; i < availableMethods.size(); ++i)
{
std::cout << i + 1 << ". " << availableMethods[i]->getMethodName() << std::endl;
}
}
bool processPayment(int methodIndex, double amount)
{
if (methodIndex < 1 || methodIndex > static_cast<int>(availableMethods.size()))
{
std::cout << "无效的支付方式选择" << std::endl;
return false;
}
return availableMethods[methodIndex - 1]->processPayment(amount);
}
};
PaymentProcessor processor;
processor.addPaymentMethod(std::make_unique<CreditCardPayment>("1234567812345678", "12/25"));
processor.addPaymentMethod(std::make_unique<PayPalPayment>("user@example.com"));
processor.addPaymentMethod(std::make_unique<BankTransferPayment>("987654321", "中国银行"));
processor.displayAvailableMethods();
std::cout << "\n模拟支付处理:" << std::endl;
processor.processPayment(1, 150.0); // 信用卡支付
processor.processPayment(2, 200.0); // PayPal支付
processor.processPayment(3, 300.0); // 银行转账
std::cout << "多态使得添加新的支付方式变得容易,无需修改现有代码" << std::endl;
}
};
class AdvancedPolymorphismTechniques
{
public:
void demonstrateAdvancedTechniques()
{
std::cout << "\n=== 高级多态技术 ===" << std::endl;
demonstrateMultipleInheritance();
demonstrateVirtualInheritance();
demonstrateTypeIdAndDynamicCast();
demonstrateCRTP();
}
private:
void demonstrateMultipleInheritance()
{
std::cout << "\n--- 多重继承中的多态 ---" << std::endl;
class Printable
{
public:
virtual void print() const = 0;
virtual ~Printable() = default;
};
class Drawable
{
public:
virtual void draw() const = 0;
virtual ~Drawable() = default;
};
class Shape : public Printable, public Drawable
{
protected:
std::string name;
public:
explicit Shape(const std::string& shapeName) : name(shapeName)
{
}
void print() const override
{
std::cout << "打印形状: " << name << std::endl;
}
};
class Circle : public Shape
{
private:
double radius;
public:
Circle(double r) : Shape("圆形"), radius(r)
{
}
void draw() const override
{
std::cout << "绘制圆形,半径: " << radius << std::endl;
}
void print() const override
{
Shape::print();
std::cout << "具体信息: 圆形,半径=" << radius << std::endl;
}
};
Circle circle(5.0);
// 通过不同基类接口访问
Printable& printable = circle;
Drawable& drawable = circle;
printable.print();
drawable.draw();
// 动态转换
Circle* circlePtr = dynamic_cast<Circle*>(&printable);
if (circlePtr)
{
std::cout << "成功转换为Circle指针" << std::endl;
}
}
void demonstrateVirtualInheritance()
{
std::cout << "\n--- 虚继承解决菱形问题 ---" << std::endl;
class Animal
{
protected:
std::string species;
public:
explicit Animal(const std::string& spec) : species(spec)
{
std::cout << "Animal构造函数: " << species << std::endl;
}
virtual void makeSound() const = 0;
virtual ~Animal() = default;
};
class Mammal : virtual public Animal
{
protected:
bool hasFur;
public:
Mammal(const std::string& spec, bool fur)
: Animal(spec), hasFur(fur)
{
std::cout << "Mammal构造函数" << std::endl;
}
void breathe() const
{
std::cout << species << " 用肺呼吸" << std::endl;
}
};
class WingedAnimal : virtual public Animal
{
protected:
double wingspan;
public:
WingedAnimal(const std::string& spec, double span)
: Animal(spec), wingspan(span)
{
std::cout << "WingedAnimal构造函数" << std::endl;
}
void fly() const
{
std::cout << species << " 在飞行,翼展: " << wingspan << std::endl;
}
};
class Bat : public Mammal, public WingedAnimal
{
public:
Bat()
: Animal("蝙蝠"),
Mammal("蝙蝠", true),
WingedAnimal("蝙蝠", 0.3)
{
std::cout << "Bat构造函数" << std::endl;
}
void makeSound() const override
{
std::cout << "蝙蝠发出超声波" << std::endl;
}
void displayAbilities() const
{
breathe();
fly();
makeSound();
}
};
Bat bat;
bat.displayAbilities();
std::cout << "虚继承确保Animal子对象只被创建一次" << std::endl;
}
void demonstrateTypeIdAndDynamicCast()
{
std::cout << "\n--- 运行时类型信息 ---" << std::endl;
class Base
{
public:
virtual ~Base() = default;
};
class Derived1 : public Base
{
public:
void specificMethod1()
{
std::cout << "Derived1特定方法" << std::endl;
}
};
class Derived2 : public Base
{
public:
void specificMethod2()
{
std::cout << "Derived2特定方法" << std::endl;
}
};
Base* objects[] = {new Derived1(), new Derived2(), new Base()};
for (int i = 0; i < 3; ++i)
{
std::cout << "对象 " << i << " 类型: " << typeid(*objects[i]).name() << std::endl;
// 使用dynamic_cast进行安全的向下转型
if (Derived1* d1 = dynamic_cast<Derived1*>(objects[i]))
{
d1->specificMethod1();
}
else if (Derived2* d2 = dynamic_cast<Derived2*>(objects[i]))
{
d2->specificMethod2();
}
else
{
std::cout << "不是Derived1或Derived2类型" << std::endl;
}
std::cout << "---" << std::endl;
}
// 清理内存
for (int i = 0; i < 3; ++i)
{
delete objects[i];
}
}
void demonstrateCRTP()
{
std::cout << "\n--- 奇异递归模板模式(CRTP) ---" << std::endl;
// 基类模板
template<typename Derived>
class Comparable
{
public:
bool operator==(const Comparable& other) const
{
return static_cast<const Derived&>(*this).getValue() ==
static_cast<const Derived&>(other).getValue();
}
bool operator!=(const Comparable& other) const
{
return !(*this == other);
}
};
class Point : public Comparable<Point>
{
private:
int x, y;
public:
Point(int xVal, int yVal) : x(xVal), y(yVal)
{
}
int getValue() const
{
return x * 1000 + y; // 简单的哈希值
}
void display() const
{
std::cout << "点(" << x << ", " << y << ")" << std::endl;
}
};
Point p1(1, 2);
Point p2(1, 2);
Point p3(3, 4);
p1.display();
p2.display();
p3.display();
std::cout << "p1 == p2: " << (p1 == p2) << std::endl;
std::cout << "p1 == p3: " << (p1 == p3) << std::endl;
std::cout << "p1 != p3: " << (p1 != p3) << std::endl;
std::cout << "CRTP在编译期提供多态行为,无运行时开销" << std::endl;
}
};
int main()
{
PolymorphismDeepDive dive;
dive.demonstratePolymorphism();
AdvancedPolymorphismTechniques advanced;
advanced.demonstrateAdvancedTechniques();
return 0;
}
这个示例深入解析了多态性的实现原理和应用:
- 基础多态:通过动物类层次展示了多态的基本概念和行为。
- 虚函数表:分析了虚函数表的实现机制和内存布局。
- 虚析构函数:强调了在基类中使用虚析构函数的重要性。
- 纯虚函数:展示了抽象类和接口的设计方法。
- 多态容器:演示了在容器中管理多态对象的最佳实践。
AdvancedPolymorphismTechniques类探讨了高级多态技术:
- 多重继承:展示了在复杂继承关系中的多态行为。
- 虚继承:解决了菱形继承问题。
- 类型信息:使用typeid和dynamic_cast进行运行时类型识别。
- CRTP:介绍了编译期多态技术。
多态是面向对象编程中最强大的特性之一,它使得代码更加灵活、可扩展和可维护。正确理解和使用多态机制,可以显著提高软件设计的质量和开发效率。
结论
面向对象编程是现代软件开发的基石,而C++提供了完整且高效的面向对象支持。通过本章的深入探讨,我们系统性地分析了面向对象的核心概念、类与对象的设计原理、成员访问控制机制以及多态性的实现方式。
面向对象编程通过封装、继承和多态这三个基本特性,提供了一种更加自然和有效的软件建模方法。封装隐藏了实现细节,提供了清晰的接口;继承支持代码复用和层次化设计;多态提高了代码的灵活性和可扩展性。理解这些特性的内在原理和正确使用方法,对于构建高质量的软件系统至关重要。
在类设计方面,合理使用访问控制、正确实现特殊成员函数、遵循面向对象设计原则,都是创建健壮、可维护类的基础。多态机制作为面向对象编程的灵魂,通过虚函数和动态绑定实现了运行时灵活性,为设计模式和框架开发提供了理论基础。
现代C++在保持面向对象优势的同时,引入了移动语义、智能指针、模板元编程等新特性,进一步提高了程序的性能和表达能力。掌握这些现代特性,结合面向对象的经典原则,可以使C++程序员在面对复杂软件系统时游刃有余。
面向对象编程不仅是一种技术,更是一种思维方式。通过对象的角度看待问题,通过类和关系组织代码,通过接口和实现分离关注点,可以构建出更加清晰、灵活和可维护的软件架构。这种思维方式的价值,远远超出了任何特定语言或技术的范畴。
更多推荐


所有评论(0)