烤面筋 Day 04
单例模式
1. 单例模式是什么?有哪些单例模式?
答:单例模式是一种设计模式,旨在确保一个类在整个应用程序的生命周期当中只有一个实例,提供一个全局访问点来获取该实例。
有一般的单例模式(用 static 修饰成员函数和 static 的局部变量),饿汉式单例模式,懒汉式单例模式,还有就是个人比较常用的 CRTP (声明单例的通用模板类)
2. 分别介绍一下这几种单例模式?
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| class Singleton { public: static Singleton& GetInstance() { static Singleton instance; return instance; } ~Singleton() = default; private: Singleton() = default; Singleton(const Singleton&) = delete; Singleton& operator=(const Singleton&) = delete; };
|
- 饿汉式单例模式:静态成员指针变量 + cpp 文件定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| class Singleton { public: ~Singleton() = default; static Singleton* GetInstance() { if(instance == nullptr) instance = new Singleton(); return instance; } private: static Singleton* instance; Singleton() = default; Singleton(const Singleton&) = delete; Singleton& operator=(const Singleton&) = delete; };
|
同时在 cpp 文件中定义 instance 实例
1
| Singleton* Singleton::instance = Singleton::GetInstance();
|
- 懒汉式单例模式: 智能指针 +
once_flag
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| #include <mutex> #include <memory>
class Singleton { public: ~Singleton() = default; static std::shared_ptr<Singleton> GetInstance() { static std::once_flag flag; std::call_once(flag, [](){ instance = std::shared_ptr<Singleton>(new Singleton()); }); return instance; } private: static std::shared_ptr<Singleton> instance; Singleton() = default; Singleton(const Singleton&) = delete; Singleton& operator=(const Singleton&) = delete; };
|
3. CRTP 是什么?能不能实现一下?
答:是一种将派生类作为模板参数传递给基类的技术,即一个类继承以自身为模板参数的基类。
基类代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| #include <memory> #include <mutex>
template <typename T> class Singleton { protected: Singleton() = default; Singleton(const Singleton<T>& other) = delete; Singleton& operator=(const Singleton<T>& other) = delete; static std::shared_ptr<T> _instance; public: ~Singleton() = default; static std::shared_ptr<T> GetInstance() { static std::once_flag flag; std::call_once(flag, [&](){ _instance = std::shared_ptr<T>(new T); }); return _instance; } };
template <typename T> std::shared_ptr<T> Singleton<T>::_instance = nullptr;
|
派生类代码:
1 2 3 4 5 6 7
| class SingleNet : public Singleton<SingleNet> { private: SingleNet() = default; friend class Singleton<SingleNet>; public: ~SingleNet() = default; };
|
观察者模式
1. 什么是观察者模式?
答:观察者模式 是一种行为设计模式。它定义了对象间的一种 一对多 的依赖关系,使得每当一个对象状态发生改变时,所有依赖于它的对象都会得到通知并被自动更新。
2. 你觉得里面的重点是什么?
3. 实现一下观察者模式吧
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| #include <iostream> #include <vector> #include <memory> #include <mutex> #include <algorithm> #include <string>
class Observer : public std::enable_shared_from_this<Observer> { public: virtual ~Observer() = default; virtual void update(const std::string& state) = 0; };
class Subject { public: void attach(std::weak_ptr<Observer> observer) { std::lock_guard<std::mutex> lock(_mtx); _observers.push_back(observer); }
void setState(std::string state) { std::vector<std::shared_ptr<Observer>> active_observers; { std::lock_guard<std::mutex> lock(_mtx); _state = state;
auto it = _observers.begin(); while (it != _observers.end()) { if (auto obj = it->lock()) { active_observers.push_back(obj); ++it; } else { it = _observers.erase(it); } } }
for (const auto& obs : active_observers) { obs->update(_state); } }
private: std::string _state; std::vector<std::weak_ptr<Observer>> _observers; std::mutex _mtx; };
class Worker : public Observer { public: Worker(std::string name) : _name(name) {} void update(const std::string& state) override { std::cout << "Worker " << _name << " received: " << state << std::endl; } private: std::string _name; };
|
Inline 内联函数
1. 内联函数的实现机制?
答:内联函数是向编译器发出的一个建议,请求将函数调用替换为函数体本身。
目的是消除函数调用的开销(如压栈、跳转、返回等),对于频繁调用的小函数性能提升明显。
2. 编译器一定会内联吗?
答:不一定会内联。编译器会根据复杂的启发式算法自行决定。
如果函数过大或者过于复杂或者函数是虚函数(内联是编译时确定,虚函数是运行时确定的)的情况下,编译器会拒绝内联。同时现代的编译器非常聪明,即使没有写 inline 关键字,只要它认为有益且符合条件,也会自动进行优化内联