MST

星途 面试题库

面试题:C++抽象基类在复杂设计模式中的应用

在设计模式中,抽象基类经常扮演重要角色。以策略模式为例,阐述如何使用抽象基类来定义一系列算法的抽象,以及如何在具体环境中通过派生类实现不同的策略。请详细说明涉及到的类结构、成员函数以及对象交互过程,同时分析这种设计方式的优点和可能存在的缺点。
24.7万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

1. 类结构

  • 抽象基类:定义了一系列算法的抽象接口。例如,在策略模式中,可命名为Strategy抽象基类。
  • 具体派生类:继承自抽象基类,实现具体的算法策略。如ConcreteStrategyAConcreteStrategyB等。
  • 上下文类:持有一个抽象基类的指针或引用,用于调用具体策略。

2. 成员函数

  • 抽象基类
    • 包含纯虚函数,这些函数定义了具体策略需要实现的接口。例如virtual void execute() = 0;,不同的策略将以不同方式实现此execute函数。
  • 具体派生类
    • 实现抽象基类中的纯虚函数。例如ConcreteStrategyA类会实现void execute() { /*具体策略A的实现代码*/ }
  • 上下文类
    • 包含一个指向抽象基类的成员变量,例如Strategy* strategy;
    • 提供设置策略的函数,如void setStrategy(Strategy* newStrategy) { strategy = newStrategy; }
    • 提供调用策略的函数,如void contextExecute() { if(strategy) strategy->execute(); }

3. 对象交互过程

  1. 创建具体策略对象,如ConcreteStrategyA* strategyA = new ConcreteStrategyA();
  2. 创建上下文对象,如Context context;
  3. 将具体策略对象设置到上下文对象中,context.setStrategy(strategyA);
  4. 上下文对象调用策略,context.contextExecute();,此时会执行ConcreteStrategyAexecute方法。如果之后想切换策略,可创建新的具体策略对象并设置到上下文对象中,如ConcreteStrategyB* strategyB = new ConcreteStrategyB(); context.setStrategy(strategyB);,再次调用contextExecute就会执行ConcreteStrategyBexecute方法。

4. 优点

  • 可维护性高:具体策略的实现与上下文分离,当需要修改某个策略时,只需修改对应的具体派生类,不影响其他部分。
  • 可扩展性强:新增策略非常容易,只需创建一个新的派生类并实现抽象基类的接口即可,符合开闭原则。
  • 灵活性好:上下文可以在运行时动态切换策略,根据不同的情况使用不同的算法。

5. 可能存在的缺点

  • 增加系统复杂性:引入了抽象基类和多个派生类,使得类的数量增多,系统结构变得复杂,对于简单场景可能过度设计。
  • 客户端需要了解策略细节:客户端需要知道有哪些具体策略可供选择,并负责创建和设置具体策略对象,增加了客户端的使用难度。