首页 > 应用开发 > IT综合 > C++面向对象进阶:抽象机制与设计模式实践
# C++面向对象进阶:抽象机制与设计模式实践
## 抽象类与接口设计原理
在C++面向对象编程中,抽象类与接口是实现多态性和代码灵活性的关键机制。抽象类通过纯虚函数定义接口规范,强制派生类提供具体实现。
```cpp
// 抽象类基本定义
class Shape {
protected:
std::string name_;
public:
explicit Shape(const std::string& name) : name_(name) {}
virtual ~Shape() = default; // 虚析构函数支持多态销毁
// 纯虚函数 - 定义接口
virtual double area() const = 0;
virtual double perimeter() const = 0;
virtual void draw() const = 0;
// 非纯虚函数 - 提供部分实现
virtual void displayInfo() const {
std::cout << "形状: " << name_ << std::endl;
std::cout << "面积: " << area() << std::endl;
std::cout << "周长: " << perimeter() << std::endl;
}
// 普通成员函数
const std::string& name() const { return name_; }
};
// 具体派生类实现
class Circle : public Shape {
private:
double radius_;
public:
explicit Circle(double radius)
: Shape("圆形"), radius_(radius) {}
// 实现纯虚函数
double area() const override {
return 3.14159 * radius_ * radius_;
}
double perimeter() const override {
return 2 * 3.14159 * radius_;
}
void draw() const override {
std::cout << "绘制圆形,半径: " << radius_ << std::endl;
}
};
// 使用抽象类
void process_shape(const Shape& shape) {
shape.displayInfo(); // 多态调用
shape.draw();
}
```
## 接口设计与实现分离
### 纯抽象接口
```cpp
// 纯抽象接口定义
class IReadable {
public:
virtual ~IReadable() = default;
// 纯虚函数定义接口
virtual std::string read() = 0;
virtual bool isAvailable() const = 0;
// 禁止拷贝
IReadable(const IReadable&) = delete;
IReadable& operator=(const IReadable&) = delete;
protected:
IReadable() = default; // 保护构造函数,只能通过派生类实例化
};
class IWritable {
public:
virtual ~IWritable() = default;
virtual void write(const std::string& data) = 0;
virtual bool canWrite() const = 0;
};
// 实现接口的类
class FileHandler : public IReadable, public IWritable {
private:
std::string filename_;
std::fstream file_;
public:
explicit FileHandler(const std::string& filename)
: filename_(filename) {}
bool open() {
file_.open(filename_, std::ios::in | std::ios::out);
return file_.is_open();
}
// 实现IReadable接口
std::string read() override {
std::string content;
std::getline(file_, content, '\0');
return content;
}
bool isAvailable() const override {
return file_.is_open();
}
// 实现IWritable接口
void write(const std::string& data) override {
if (canWrite()) {
file_ << data;
}
}
bool canWrite() const override {
return file_.is_open() && (file_.good());
}
};
// 接口使用示例
void process_data(IReadable& reader, IWritable& writer) {
if (reader.isAvailable()) {
std::string data = reader.read();
if (writer.canWrite()) {
writer.write("处理后的数据: " + data);
}
}
}
```
## 设计模式应用实践
### 工厂方法模式
```cpp
// 抽象产品
class Document {
public:
virtual ~Document() = default;
virtual void open() = 0;
virtual void save() = 0;
virtual void close() = 0;
};
// 具体产品
class WordDocument : public Document {
public:
void open() override {
std::cout << "打开Word文档" << std::endl;
}
void save() override {
std::cout << "保存Word文档" << std::endl;
}
void close() override {
std::cout << "关闭Word文档" << std::endl;
}
};
class ExcelDocument : public Document {
public:
void open() override {
std::cout << "打开Excel文档" << std::endl;
}
void save() override {
std::cout << "保存Excel文档" << std::endl;
}
void close() override {
std::cout << "关闭Excel文档" << std::endl;
}
};
// 抽象创建者
class Application {
public:
virtual ~Application() = default;
// 工厂方法
virtual std::unique_ptr<Document> createDocument() = 0;
void newDocument() {
auto doc = createDocument();
doc->open();
// 处理文档...
doc->save();
doc->close();
}
};
// 具体创建者
class WordApplication : public Application {
public:
std::unique_ptr<Document> createDocument() override {
return std::make_unique<WordDocument>();
}
};
class ExcelApplication : public Application {
public:
std::unique_ptr<Document> createDocument() override {
return std::make_unique<ExcelDocument>();
}
};
// 使用工厂方法
void factory_method_demo() {
std::unique_ptr<Application> app;
// 根据配置选择应用类型
std::string app_type = "word"; // 从配置读取
if (app_type == "word") {
app = std::make_unique<WordApplication>();
} else if (app_type == "excel") {
app = std::make_unique<ExcelApplication>();
}
if (app) {
app->newDocument();
}
}
```
### 策略模式
```cpp
// 策略接口
class SortingStrategy {
public:
virtual ~SortingStrategy() = default;
virtual void sort(std::vector<int>& data) const = 0;
virtual std::string name() const = 0;
};
// 具体策略
class QuickSortStrategy : public SortingStrategy {
public:
void sort(std::vector<int>& data) const override {
std::sort(data.begin(), data.end());
std::cout << "使用快速排序" << std::endl;
}
std::string name() const override {
return "快速排序";
}
};
class BubbleSortStrategy : public SortingStrategy {
public:
void sort(std::vector<int>& data) const override {
for (size_t i = 0; i < data.size(); ++i) {
for (size_t j = 0; j < data.size() - i - 1; ++j) {
if (data[j] > data[j + 1]) {
std::swap(data[j], data[j + 1]);
}
}
}
std::cout << "使用冒泡排序" << std::endl;
}
std::string name() const override {
return "冒泡排序";
}
};
class MergeSortStrategy : public SortingStrategy {
public:
void sort(std::vector<int>& data) const override {
// 归并排序实现
mergeSort(data, 0, data.size() - 1);
std::cout << "使用归并排序" << std::endl;
}
std::string name() const override {
return "归并排序";
}
private:
void mergeSort(std::vector<int>& data, int left, int right) const {
if (left < right) {
int mid = left + (right - left) / 2;
mergeSort(data, left, mid);
mergeSort(data, mid + 1, right);
merge(data, left, mid, right);
}
}
void merge(std::vector<int>& data, int left, int mid, int right) const {
// 合并实现
}
};
// 上下文类
class Sorter {
private:
std::unique_ptr<SortingStrategy> strategy_;
public:
explicit Sorter(std::unique_ptr<SortingStrategy> strategy)
: strategy_(std::move(strategy)) {}
void setStrategy(std::unique_ptr<SortingStrategy> strategy) {
strategy_ = std::move(strategy);
}
void executeSort(std::vector<int>& data) const {
if (strategy_) {
auto start = std::chrono::high_resolution_clock::now();
strategy_->sort(data);
auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
std::cout << strategy_->name() << "耗时: "
<< duration.count() << "微秒" << std::endl;
}
}
};
// 策略模式使用
void strategy_pattern_demo() {
std::vector<int> data = {5, 2, 8, 1, 9, 3};
Sorter sorter(std::make_unique<QuickSortStrategy>());
sorter.executeSort(data);
// 切换策略
sorter.setStrategy(std::make_unique<BubbleSortStrategy>());
sorter.executeSort(data);
// 根据数据规模选择策略
if (data.size() < 100) {
sorter.setStrategy(std::make_unique<BubbleSortStrategy>());
} else {
sorter.setStrategy(std::make_unique<QuickSortStrategy>());
}
sorter.executeSort(data);
}
```
### 观察者模式
```cpp
// 观察者接口
class IObserver {
public:
virtual ~IObserver() = default;
virtual void update(const std::string& message) = 0;
virtual std::string getName() const = 0;
};
// 主题接口
class ISubject {
public:
virtual ~ISubject() = default;
virtual void attach(std::shared_ptr<IObserver> observer) = 0;
virtual void detach(std::shared_ptr<IObserver> observer) = 0;
virtual void notify() = 0;
};
// 具体主题
class WeatherStation : public ISubject {
private:
std::vector<std::shared_ptr<IObserver>> observers_;
float temperature_;
float humidity_;
float pressure_;
public:
void setMeasurements(float temp, float humidity, float pressure) {
temperature_ = temp;
humidity_ = humidity;
pressure_ = pressure;
notify(); // 通知所有观察者
}
void attach(std::shared_ptr<IObserver> observer) override {
observers_.push_back(observer);
}
void detach(std::shared_ptr<IObserver> observer) override {
observers_.erase(
std::remove(observers_.begin(), observers_.end(), observer),
observers_.end());
}
void notify() override {
std::string message = "温度: " + std::to_string(temperature_)
+ "℃, 湿度: " + std::to_string(humidity_)
+ "%, 气压: " + std::to_string(pressure_) + "hPa";
for (const auto& observer : observers_) {
observer->update(message);
}
}
};
// 具体观察者
class Display : public IObserver {
private:
std::string name_;
public:
explicit Display(const std::string& name) : name_(name) {}
void update(const std::string& message) override {
std::cout << name_ << " 显示: " << message << std::endl;
}
std::string getName() const override {
return name_;
}
};
class Logger : public IObserver {
<"bc.yunruiwater.cn"><"de.sxyicheng.cn"><"fg.jsnjz.cn">
private:
std::ofstream log_file_;
public:
explicit Logger(const std::string& filename) {
log_file_.open(filename, std::ios::app);
}
~Logger() {
if (log_file_.is_open()) {
log_file_.close();
}
}
void update(const std::string& message) override {
if (log_file_.is_open()) {
auto now = std::chrono::system_clock::now();
auto time = std::chrono::system_clock::to_time_t(now);
log_file_ << std::ctime(&time) << " - " << message << std::endl;
}
}
std::string getName() const override {
return "数据记录器";
}
};
// 观察者模式使用
void observer_pattern_demo() {
auto station = std::make_shared<WeatherStation>();
auto display1 = std::make_shared<Display>("客厅显示屏");
auto display2 = std::make_shared<Display>("卧室显示屏");
auto logger = std::make_shared<Logger>("weather_log.txt");
station->attach(display1);
station->attach(display2);
station->attach(logger);
// 模拟天气数据变化
station->setMeasurements(25.5, 65.0, 1013.25);
station->setMeasurements(26.0, 63.0, 1012.75);
// 移除观察者
station->detach(display2);
station->setMeasurements(24.5, 67.0, 1014.0);
}
```
## 适配器模式
```cpp
// 遗留系统接口
class LegacyRectangle {
public:
void draw(int x1, int y1, int x2, int y2) const {
std::cout << "绘制旧式矩形: (" << x1 << "," << y1
<< ") -> (" << x2 << "," << y2 << ")" << std::endl;
}
};
// 新系统接口
class Shape {
public:
virtual ~Shape() = default;
virtual void draw() const = 0;
};
// 适配器
class RectangleAdapter : public Shape {
private:
LegacyRectangle legacy_rect_;
int x_, y_, width_, height_;
public:
RectangleAdapter(int x, int y, int width, int height)
: x_(x), y_(y), width_(width), height_(height) {}
void draw() const override {
// 适配旧接口
legacy_rect_.draw(x_, y_, x_ + width_, y_ + height_);
}
};
// 使用适配器
void adapter_pattern_demo() {
std::vector<std::unique_ptr<Shape>> shapes;
shapes.push_back(std::make_unique<RectangleAdapter>(10, 10, 50, 30));
shapes.push_back(std::make_unique<RectangleAdapter>(20, 20, 40, 60));
for (const auto& shape : shapes) {
shape->draw();
}
}
```
## 装饰器模式
```cpp
// 组件接口
class Beverage {
public:
virtual ~Beverage() = default;
virtual std::string getDescription() const = 0;
virtual double cost() const = 0;
};
// 具体组件
class Coffee : public Beverage {
public:
std::string getDescription() const override {
return "咖啡";
}
double cost() const override {
return 20.0;
}
};
class Tea : public Beverage {
public:
std::string getDescription() const override {
return "茶";
}
double cost() const override {
return 15.0;
}
};
// 装饰器基类
class CondimentDecorator : public Beverage {
protected:
std::unique_ptr<Beverage> beverage_;
public:
explicit CondimentDecorator(std::unique_ptr<Beverage> beverage)
: beverage_(std::move(beverage)) {}
std::string getDescription() const override {
return beverage_->getDescription();
}
double cost() const override {
return beverage_->cost();
}
};
// 具体装饰器
class MilkDecorator : public CondimentDecorator {
public:
explicit MilkDecorator(std::unique_ptr<Beverage> beverage)
: CondimentDecorator(std::move(beverage)) {}
std::string getDescription() const override {
return beverage_->getDescription() + ", 加牛奶";
}
double cost() const override {
return beverage_->cost() + 5.0;
}
};
class SugarDecorator : public CondimentDecorator {
public:
explicit SugarDecorator(std::unique_ptr<Beverage> beverage)
: CondimentDecorator(std::move(beverage)) {}
std::string getDescription() const override {
return beverage_->getDescription() + ", 加糖";
}
double cost() const override {
return beverage_->cost() + 2.0;
}
};
// 装饰器模式使用
void decorator_pattern_demo() {
// 创建基础饮料
auto coffee = std::make_unique<Coffee>();
std::cout << coffee->getDescription()
<< " 价格: " << coffee->cost() << std::endl;
// 动态添加装饰
auto milkCoffee = std::make_unique<MilkDecorator>(std::move(coffee));
std::cout << milkCoffee->getDescription()
<< " 价格: " << milkCoffee->cost() << std::endl;
auto sugarMilkCoffee = std::make_unique<SugarDecorator>(std::move(milkCoffee));
std::cout << sugarMilkCoffee->getDescription()
<< " 价格: " << sugarMilkCoffee->cost() << std::endl;
}
```
## 模板方法模式
```cpp
// 抽象基类定义算法骨架
class DataProcessor {
public:
virtual ~DataProcessor() = default;
// 模板方法
void process() {
readData();
validateData();
transformData();
saveData();
cleanup();
}
protected:
// 必须由子类实现
virtual void readData() = 0;
virtual void transformData() = 0;
// 可选由子类覆盖
virtual void validateData() {
std::cout << "执行默认数据验证" << std::endl;
<"hi.csxthr.com"><"lm.zhaiLimao.com"><"no.yunruiwater.cn">
}
virtual void saveData() {
std::cout << "保存数据到默认位置" << std::endl;
}
virtual void cleanup() {
std::cout << "执行默认清理操作" << std::endl;
}
};
// 具体实现
class CSVProcessor : public DataProcessor {
protected:
void readData() override {
std::cout << "读取CSV文件数据" << std::endl;
}
void transformData() override {
std::cout << "转换CSV数据格式" << std::endl;
}
void saveData() override {
std::cout << "保存CSV数据到数据库" << std::endl;
}
};
class JSONProcessor : public DataProcessor {
protected:
void readData() override {
std::cout << "读取JSON文件数据" << std::endl;
}
void transformData() override {
std::cout << "解析JSON数据" << std::endl;
}
void validateData() override {
std::cout << "验证JSON数据格式" << std::endl;
}
void cleanup() override {
std::cout << "清理JSON解析缓存" << std::endl;
}
};
// 使用模板方法
void template_method_demo() {
CSVProcessor csv_processor;
csv_processor.process();
std::cout << "\n---\n" << std::endl;
JSONProcessor json_processor;
json_processor.process();
}
```
## 高级接口设计技巧
### CRTP(奇异递归模板模式)
```cpp
// CRTP基类
template<typename Derived>
class Comparable {
public:
bool operator!=(const Derived& other) const {
return !(static_cast<const Derived&>(*this) == other);
}
bool operator<=(const Derived& other) const {
return !(other < static_cast<const Derived&>(*this));
}
bool operator>=(const Derived& other) const {
return !(static_cast<const Derived&>(*this) < other);
}
bool operator>(const Derived& other) const {
return other < static_cast<const Derived&>(*this);
}
};
// 使用CRTP
class Point : public Comparable<Point> {
private:
int x_, y_;
public:
Point(int x, int y) : x_(x), y_(y) {}
// 只需要实现==和<
bool operator==(const Point& other) const {
return x_ == other.x_ && y_ == other.y_;
}
bool operator<(const Point& other) const {
if (x_ != other.x_) return x_ < other.x_;
return y_ < other.y_;
}
// 自动获得!=, <=, >=, >运算符
};
// 测试CRTP
void crtp_demo() {
Point p1(1, 2);
Point p2(3, 4);
Point p3(1, 2);
std::cout << "p1 == p3: " << (p1 == p3) << std::endl;
std::cout << "p1 != p2: " << (p1 != p2) << std::endl;
std::cout << "p1 < p2: " << (p1 < p2) << std::endl;
std::cout << "p1 > p2: " << (p1 > p2) << std::endl;
std::cout << "p1 <= p3: " << (p1 <= p3) << std::endl;
}
```
### 类型擦除技术
```cpp
// 类型擦除包装器
class AnyDrawable {
private:
struct Concept {
virtual ~Concept() = default;
virtual void draw() const = 0;
virtual std::unique_ptr<Concept> clone() const = 0;
};
template<typename T>
struct Model : Concept {
T object;
explicit Model(T obj) : object(std::move(obj)) {}
void draw() const override {
object.draw();
}
std::unique_ptr<Concept> clone() const override {
return std::make_unique<Model<T>>(object);
}
};
std::unique_ptr<Concept> object_;
public:
template<typename T>
AnyDrawable(T obj)
: object_(std::make_unique<Model<T>>(std::move(obj))) {}
AnyDrawable(const AnyDrawable& other)
: object_(other.object_->clone()) {}
AnyDrawable& operator=(const AnyDrawable& other) {
if (this != &other) {
object_ = other.object_->clone();
}
return *this;
}
void draw() const {
if (object_) {
object_->draw();
}
}
};
// 使用类型擦除
void type_erasure_demo() {
std::vector<AnyDrawable> drawings;
struct Circle {
void draw() const { std::cout << "绘制圆形" << std::endl; }
};
struct Square {
void draw() const { std::cout << "绘制正方形" << std::endl; }
};
drawings.push_back(Circle{});
drawings.push_back(Square{});
for (const auto& drawing : drawings) {
drawing.draw();
}
}
```
C++面向对象高级特性通过抽象类、接口和设计模式,为复杂系统提供了强大的架构能力。抽象类和接口定义了清晰的契约,设计模式提供了经过验证的解决方案模板。这些技术共同构成了构建可维护、可扩展、高性能C++系统的基础。掌握这些高级特性,能够帮助开发者在面对复杂业务逻辑时,设计出优雅而高效的解决方案。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/19545/viewspace-3108948/ ,如需转载,请注明出处,否则将追究法律责任。