C++ 设计模式面试题

1. 什么是设计模式?常见的设计模式有哪些?

答案:

  • 定义软件设计中常见问题的可复用解决方案经过验证的最佳实践提高代码可维护性和可扩展性
  • 三大类创建型模式:对象创建单例模式工厂模式抽象工厂模式建造者模式原型模式结构型模式:对象组合适配器模式装饰器模式代理模式外观模式桥接模式组合模式享元模式行为型模式:对象交互观察者模式策略模式模板方法模式命令模式迭代器模式状态模式责任链模式访问者模式

2. 单例模式如何实现?

答案:

  • 懒汉式(线程不安全)
class Singleton {
    static Singleton* instance;
    Singleton() {}
public:
    static Singleton* getInstance() {
        if (instance == nullptr) {
            instance = new Singleton();
        }
        return instance;
    }
};
Singleton* Singleton::instance = nullptr;
  • 懒汉式(线程安全,双重检查锁)
class Singleton {
    static atomic<Singleton*> instance;
    static mutex mtx;
    Singleton() {}
public:
    static Singleton* getInstance() {
        Singleton* tmp = instance.load(memory_order_acquire);
        if (tmp == nullptr) {
            lock_guard<mutex> lock(mtx);
            tmp = instance.load(memory_order_relaxed);
            if (tmp == nullptr) {
                tmp = new Singleton();
                instance.store(tmp, memory_order_release);
            }
        }
        return tmp;
    }
};
  • 饿汉式(线程安全)
class Singleton {
    static Singleton instance;
    Singleton() {}
public:
    static Singleton& getInstance() {
        return instance;
    }
};
Singleton Singleton::instance;
  • Meyers单例(C++11,推荐)
class Singleton {
    Singleton() {}
public:
    static Singleton& getInstance() {
        static Singleton instance;  // 线程安全
        return instance;
    }
    
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;
};

3. 工厂模式如何实现?

答案:

  • 简单工厂
class Product {
public:
    virtual void use() = 0;
    virtual ~Product() {}
};

class ConcreteProductA : public Product {
public:
    void use() override { cout << "Product A" << endl; }
};

class ConcreteProductB : public Product {
public:
    void use() override { cout << "Product B" << endl; }
};

class Factory {
public:
    static unique_ptr<Product> createProduct(const string& type) {
        if (type == "A") return make_unique<ConcreteProductA>();
        if (type == "B") return make_unique<ConcreteProductB>();
        return nullptr;
    }
};
  • 工厂方法
class Factory {
public:
    virtual unique_ptr<Product> createProduct() = 0;
    virtual ~Factory() {}
};

class FactoryA : public Factory {
public:
    unique_ptr<Product> createProduct() override {
        return make_unique<ConcreteProductA>();
    }
};

class FactoryB : public Factory {
public:
    unique_ptr<Product> createProduct() override {
        return make_unique<ConcreteProductB>();
    }
};
  • 抽象工厂创建一系列相关对象不指定具体类

4. 观察者模式如何实现?

答案:

  • 定义一对多依赖关系对象状态改变时,通知所有依赖者也叫发布-订阅模式
  • 实现
class Observer {
public:
    virtual void update(int value) = 0;
    virtual ~Observer() {}
};

class Subject {
    vector<Observer*> observers;
    int state;
public:
    void attach(Observer* obs) {
        observers.push_back(obs);
    }
    
    void detach(Observer* obs) {
        observers.erase(remove(observers.begin(), observers.end(), obs));
    }
    
    void setState(int value) {
        state = value;
        notify();
    }
    
    void notify() {
        for (auto obs : observers) {
            obs->update(state);
        }
    }
};

class ConcreteObserver : public Observer {
    string name;
public:
    ConcreteObserver(const string& n) : name(n) {}
    
    void update(int value) override {
        cout << name << " received: " << value << endl;
    }
};
  • 使用
Subject subject;
ConcreteObserver obs1("Observer1");
ConcreteObserver obs2("Observer2");

subject.attach(&obs1);
subject.attach(&obs2);
subject.setState(10);  // 通知所有观察者

5. 策略模式如何实现?

答案:

  • 定义定义一系列算法封装每个算法使它们可以互换
  • 实现
class Strategy {
public:
    virtual int execute(int a, int b) = 0;
    virtual ~Strategy() {}
};

class AddStrategy : public Strategy {
public:
    int execute(int a, int b) override {
        return a + b;
    }
};

class MultiplyStrategy : public Strategy {
public:
    int execute(int a, int b) override {
        return a * b;
    }
};

class Context {
    unique_ptr<Strategy> strategy;
public:
    void setStrategy(unique_ptr<Strategy> s) {
        strategy = move(s);
    }
    
    int executeStrategy(int a, int b) {
        return strategy->execute(a, b);
    }
};
  • 使用
Context context;
context.setStrategy(make_unique<AddStrategy>());
cout << context.executeStrategy(3, 4) << endl;  // 7

context.setStrategy(make_unique<MultiplyStrategy>());
cout << context.executeStrategy(3, 4) << endl;  // 12

6. 装饰器模式如何实现?

答案:

  • 定义动态地给对象添加职责比继承更灵活不改变接口
  • 实现
class Component {
public:
    virtual void operation() = 0;
    virtual ~Component() {}
};

class ConcreteComponent : public Component {
public:
    void operation() override {
        cout << "ConcreteComponent" << endl;
    }
};

class Decorator : public Component {
protected:
    unique_ptr<Component> component;
public:
    Decorator(unique_ptr<Component> c) : component(move(c)) {}
    
    void operation() override {
        component->operation();
    }
};

class ConcreteDecoratorA : public Decorator {
public:
    ConcreteDecoratorA(unique_ptr<Component> c) : Decorator(move(c)) {}
    
    void operation() override {
        Decorator::operation();
        cout << "DecoratorA" << endl;
    }
};

class ConcreteDecoratorB : public Decorator {
public:
    ConcreteDecoratorB(unique_ptr<Component> c) : Decorator(move(c)) {}
    
    void operation() override {
        Decorator::operation();
        cout << "DecoratorB" << endl;
    }
};
  • 使用
auto component = make_unique<ConcreteComponent>();
auto decorated = make_unique<ConcreteDecoratorA>(move(component));
decorated = make_unique<ConcreteDecoratorB>(move(decorated));
decorated->operation();

7. 代理模式如何实现?

答案:

  • 定义为对象提供代理控制对对象的访问可以添加额外功能
  • 实现
class Subject {
public:
    virtual void request() = 0;
    virtual ~Subject() {}
};

class RealSubject : public Subject {
public:
    void request() override {
        cout << "RealSubject request" << endl;
    }
};

class Proxy : public Subject {
    unique_ptr<RealSubject> realSubject;
    
    void checkAccess() {
        cout << "Proxy: Checking access" << endl;
    }
    
    void logAccess() {
        cout << "Proxy: Logging access" << endl;
    }
    
public:
    void request() override {
        checkAccess();
        if (!realSubject) {
            realSubject = make_unique<RealSubject>();
        }
        realSubject->request();
        logAccess();
    }
};
  • 类型远程代理:不同地址空间虚拟代理:延迟创建保护代理:访问控制智能引用:引用计数等

8. 模板方法模式如何实现?

答案:

  • 定义定义算法骨架子类实现具体步骤控制子类扩展
  • 实现
class AbstractClass {
public:
    void templateMethod() {
        step1();
        step2();
        step3();
    }
    
    virtual ~AbstractClass() {}
    
protected:
    virtual void step1() = 0;
    virtual void step2() = 0;
    
    void step3() {
        cout << "AbstractClass step3" << endl;
    }
};

class ConcreteClassA : public AbstractClass {
protected:
    void step1() override {
        cout << "ConcreteClassA step1" << endl;
    }
    
    void step2() override {
        cout << "ConcreteClassA step2" << endl;
    }
};

class ConcreteClassB : public AbstractClass {
protected:
    void step1() override {
        cout << "ConcreteClassB step1" << endl;
    }
    
    void step2() override {
        cout << "ConcreteClassB step2" << endl;
    }
};
  • 应用框架设计算法框架避免代码重复

9. 适配器模式如何实现?

答案:

  • 定义将一个接口转换为另一个接口使不兼容的类可以合作也叫包装器
  • 类适配器(多继承)
class Target {
public:
    virtual void request() = 0;
    virtual ~Target() {}
};

class Adaptee {
public:
    void specificRequest() {
        cout << "Adaptee specificRequest" << endl;
    }
};

class Adapter : public Target, private Adaptee {
public:
    void request() override {
        specificRequest();
    }
};
  • 对象适配器(组合)
class Adapter : public Target {
    unique_ptr<Adaptee> adaptee;
public:
    Adapter(unique_ptr<Adaptee> a) : adaptee(move(a)) {}
    
    void request() override {
        adaptee->specificRequest();
    }
};
  • 使用场景使用第三方库接口不兼容复用现有类

10. SOLID原则是什么?

答案:

  • 单一职责原则(SRP)一个类只有一个改变的理由职责单一,高内聚
  • 开闭原则(OCP)对扩展开放,对修改关闭通过抽象实现
  • 里氏替换原则(LSP)子类可以替换父类不改变程序正确性
  • 接口隔离原则(ISP)客户端不应依赖不需要的接口接口细化
  • 依赖倒置原则(DIP)依赖抽象,不依赖具体高层模块不依赖低层模块
  • 示例
// 违反SRP
class Employee {
    void calculatePay();
    void save();
    void reportHours();
};

// 遵循SRP
class Employee {
    void calculatePay();
};
class EmployeeRepository {
    void save(Employee& emp);
};
class EmployeeReporter {
    void reportHours(Employee& emp);
};
C++面试总结 文章被收录于专栏

本专栏系统梳理C++面试高频考点,从基础语法、内存管理、STL与设计模式,到操作系统与项目实战,结合真实面试题深度解析,帮助开发者高效查漏补缺,提升技术理解与面试通过率,打造扎实的C++工程能力。

全部评论

相关推荐

KKorz:是这样的,还会定期默写抽查
点赞 评论 收藏
分享
评论
点赞
2
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务