C++单例模式参考

C++编程语言是一个应用广泛的计算机应用语言,它功能强大,在一定程度上大大提高了程序开发效率。C++单例模式也称为单件模式、单子模式。使用单例模式,保证一个类仅有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。有很多地方需要这样的功能模块,如系统的日志输出等。


单例模式有许多种实现方法,在C++中,甚至可以直接用一个全局变量做到这一点,但这样的代码显得很不优雅。定义一个单例类,使用类的私有静态指针变量指向类的唯一实例,并用一个公有静态方法获取该实例。如下面的类定义:


class CSingleton:  
{  
// 其它成员  
public:  
static CSingleton * GetInstance()  
{  
	if (m_pInstance == NULL)  
		m_pInstance = new CSingleton();  
	return m_pInstance;  
}  
private:  
	CSingleton(){};  
	static CSingleton * m_pInstance;  
} 

C++单例模式类CSingleton有以下特征:


它有一个指唯一实例的静态指针m_pInstance,并且是私有的。


它有一个公有的函数,可以获取这个唯一的实例,并在需要的时候创建该实例。


它的构造函数是私有的,这样就不能从别处创建该类的实例。


大多时候,这样的实现都不会出现问题。有经验的读者可能会问,m_pInstance指向的空间什么时候释放呢?更严重的问题是,这个实例的析构操作什么时候执行?


如果在类的析构行为中有必须的操作,比如关闭文件,释放外部资源,那么上面所示的代码无法实现这个要求。我们需要一种方法,正常地删除该实例。


可以在程序结束时调用GetInstance并对返回的指针调用delete操作。这样做可以实现功能,但是不仅很丑陋,而且容易出错。因为这样的附加代码很容易被忘记,而且也很难保证在delete之后,没有代码再调用GetInstance函数。


一个妥善的方法是让这个类自己知道在合适的时候把自己删除。或者说把删除自己的操作挂在系统中的某个合适的点上,使其在恰当的时候自动被执行。


我们知道,程序在结束的时候,系统会自动析构所有的全局变量。事实上,系统也会析构所有的类的静态成员变量,就像这些静态成员也是全局变量一样。利用这个特征,我们可以在单例类中定义一个这样的静态成员变量,而它的唯一工作就是在析构函数中删除单例类的实例。如下面的代码中的CGarbo类(Garbo意为垃圾工人):

class CSingleton:  
{  
// 其它成员  
public:  
static CSingleton * GetInstance()  
private:  
CSingleton(){};  
static CSingleton * m_pInstance;  
class CGarbo // 它的唯一工作就是在析构函数中删除
CSingleton的实例  
{  
public:  
~CGarbo()  
{  
if (CSingleton::m_pInstance)  
delete CSingleton::m_pInstance;  
}  
};  
static CGarbo Garbo; // 定义一个静态成员,在程序结束时,
系统会调用它的析构函数  
} 

类CGarbo被定义为CSingleton的私有内嵌类,以防该类被在其它地方滥用。
在程序运行结束时,系统会调用CSingleton的静态成员Garbo的析构函数,该析构函数会删除单例的唯一实例。
使用这种方法释放C++单例模式对象有以下特征:
在单例类内部定义专有的嵌套类。
在单例类内定义私有的专门用于释放的静态成员。
利用程序在结束时析构全局变量的特性,选择最终的释放时机。
使用C++单例模式的代码不需要任何操作,不必关心对象的释放。


http://developer.51cto.com/art/201002/183454.htm

<think>好的,用户想了解C++单例模式的饿汉式实现方式。首先,我需要回顾一下单例模式的基本概念,确保自己理解正确。单例模式确保一个类只有一个实例,并提供全局访问点。饿汉式是其中一种实现方式,特点是类加载时就初始化实例,这样可能会提前占用资源,但线程安全。 接下来,我需要参考提供的引用内容。引用[1]提到饿汉式和懒汉式的区别,引用[3]说明饿汉式是静态初始化,类加载时就创建实例,线程安全。而懒汉式需要处理多线程问题。用户明确问的是饿汉式,所以重点在如何静态初始化。 现在,构造回答的结构。首先解释饿汉式的定义和特点,然后给出具体的代码示例。需要注意C++中的静态成员变量和静态函数的实现方式。根据引用[2],实例应该用static修饰,并且构造函数私有化,防止外部实例化。 代码部分,需要展示类的定义,包括私有的静态实例指针,私有的构造函数,公有的获取实例方法。同时,要在类外初始化静态成员,确保在程序开始前就创建实例。这部分容易出错,需要确认语法正确,比如静态成员在类外的初始化方式。 另外,要强调饿汉式的优缺点。优点是线程安全,因为实例在main函数执行前就已经初始化,不需要考虑多线程竞争。缺点是可能造成资源浪费,如果实例未被使用,或者初始化耗时较长影响程序启动速度。 可能还需要对比懒汉式,帮助用户理解不同场景下的选择。但用户的问题只针对饿汉式,所以简要提及即可,避免信息过载。 检查是否有遗漏点,比如拷贝构造函数和赋值操作符需要禁用,防止通过拷贝创建新实例。这也是单例模式常见的注意点,应该在代码中体现为删除这两个函数。 最后,确保回答符合用户的要求:结构清晰,步骤详细,引用正确。引用[3]提到饿汉式是静态初始化,线程安全,需要引用到相关部分。同时,生成相关问题,如优缺点、线程安全、与懒汉式的对比等,帮助用户进一步学习。</think>### C++单例模式饿汉式实现详解 饿汉式单例模式的核心特征是**在类加载阶段就完成实例化**,通过静态成员变量直接初始化单例对象。这种方式具有**天然线程安全**特性,适用于初始化耗时短且需要频繁访问的场景[^3]。 #### 实现步骤分解 1. **构造函数私有化**:禁止外部直接实例化 2. **声明静态实例指针**:存储唯一实例 3. **定义静态访问方法**:提供全局访问接口 4. **禁用拷贝和赋值**:防止意外复制实例 #### 完整代码示例 ```cpp class Singleton { private: // 静态成员变量声明(类内) static Singleton* instance; // 禁用默认构造函数 Singleton() = default; // 禁用拷贝和赋值 Singleton(const Singleton&) = delete; void operator=(const Singleton&) = delete; public: // 全局访问点 static Singleton* getInstance() { return instance; } }; // 静态成员变量初始化(类外) Singleton* Singleton::instance = new Singleton(); ``` #### 关键特性解析 $$ \text{内存分配时间} \quad T_{alloc} = \text{程序启动时} $$ 1. **线程安全性**:实例在`main()`函数执行前完成初始化,规避了多线程竞争问题 2. **资源占用**:即使从未使用也会占用内存空间 3. **访问效率**:直接返回已存在的指针,时间复杂度为$O(1)$ #### 应用场景建议 - 需要高频访问的核心管理器(如内存池、日志系统) - 初始化耗时短(<50ms)的基础服务组件 - 对线程安全有严格要求的系统级服务
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值