1. C++11中的特殊类设计模式解析
在C++11标准发布后,类设计模式迎来了革命性的变化。特殊类设计作为面向对象编程中的重要概念,指的是那些具有特殊构造、拷贝或行为语义的类。我从业十余年来,见过太多因为特殊类设计不当导致的资源泄漏和线程安全问题。
特殊类通常包含以下几种典型形式:
- 不可拷贝类(non-copyable)
- 不可移动类(non-movable)
- 只能栈上分配的类
- 只能堆上分配的类
- 单例类(singleton)
这些特殊类在系统架构中扮演着关键角色。比如在游戏引擎开发中,渲染器通常设计为单例;在金融交易系统中,订单工厂往往被设计为不可拷贝的类。理解这些设计模式的区别和适用场景,是成为高级C++开发者的必经之路。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 单例模式的五种经典实现方式
2.1 基础懒汉式(线程不安全版本)
这是最简单的单例实现,也是我面试候选人时常问的起点:
cpp复制class Singleton {
public:
static Singleton* getInstance() {
if (instance == nullptr) {
instance = new Singleton();
}
return instance;
}
private:
Singleton() = default;
~Singleton() = default;
static Singleton* instance;
};
Singleton* Singleton::instance = nullptr;
这个版本的问题显而易见:多线程环境下,多个线程可能同时进入if判断,导致创建多个实例。我在2015年参与的一个分布式项目就曾因此导致内存泄漏,最终花费两天时间才定位到这个"简单"问题。
2.2 加锁的线程安全懒汉式
为了解决线程安全问题,最直观的做法是加锁:
cpp复制class Singleton {
public:
static Singleton* getInstance() {
std::lock_guard<std::mutex> lock(mutex);
if (instance == nullptr) {
instance = new Singleton();
}
return instance;
}
private:
Singleton() = default;
~Singleton() = default;
static Singleton* instance;
static std::mutex mutex;
};
Singleton* Singleton::instance = nullptr;
std::mutex Singleton::mutex;
这种实现虽然线程安全了,但每次获取实例都要加锁,性能堪忧。在2018年做高频交易系统时,我们实测发现这种实现会导致吞吐量下降30%。
