惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
爱范儿
爱范儿
J
Java Code Geeks
L
LangChain Blog
V
V2EX
大猫的无限游戏
大猫的无限游戏
S
SegmentFault 最新的问题
博客园 - Franky
Microsoft Azure Blog
Microsoft Azure Blog
Jina AI
Jina AI
Blog — PlanetScale
Blog — PlanetScale
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
The Cloudflare Blog
博客园 - 司徒正美
B
Blog
G
Google Developers Blog
Stack Overflow Blog
Stack Overflow Blog
罗磊的独立博客
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Apple Machine Learning Research
Apple Machine Learning Research
Engineering at Meta
Engineering at Meta
MyScale Blog
MyScale Blog
有赞技术团队
有赞技术团队
Hugging Face - Blog
Hugging Face - Blog

博客园 - 周伟

域名解析文件hosts文件是什么?如何修改hosts文件? PowerDesigner 使用心得 实现TOMCAT服务下一个ip绑定多域名绑定的方法 CSV扩展类 C++导入导出CSV文件 struct+vector实现树结构 WebService 随写 mysql相关文章收集 Linux下两种自动启动Tomcat的方法 linux自动启动mysql LINUX下mysql的大小写区分设置 Jdom使用指南 vector+struct在数据接口中的应用 UML用例中使用和扩展意义 枚举和字符串互转 单件模式的C++标准实现 设计模式 Add Crash Reporting to Your Applications with the CrashRpt Library Singleton的C++实现 及相关问题
设计模式——单键模式(singleton)C++实现
周伟 · 2009-05-05 · via 博客园 - 周伟

单键模式保证一个类只有一个实例!
实现的方法一般如下:
1,私有化所有构造函数,禁止外部随意构造对象;
2,实现该类的唯一对象,并使该类的使用者通过某种方法访问该对象。


遵循这种思想,我想到一个最简单的实现,便是定义该类的一个public的静态数据成员供外部使用即可。
class Singleton
{
private:
    // 所有构造函数
public:
    static Singleton ms_Instance;
    ....
};
但是仔细一想,该方法有问题。C++中非局部静态对象的构造时机不能确定,如果在该对象尚未构造时使用该对象就会出问题;再者该静态数据成员可能会在main函数之前并已经初始化,但是该对象使用的某些数据可能要等到程序进入main函数中才会有效,这样该对象构造可能失败。因此,该方法不能使用。


既然不能直接使用静态成员对象,那可以使用指针,在使用的时候再生成该类唯一的对象,我得到如下代码:
class Singleton
{
    // 私有所有构造函数
public:
    Singleton& GetInstance(void)
    {
        if (ms_pInstance == NULL)
            ms_pInstance = new Singleton();
        return *ms_pInstance;
    }
private:
    static Singleton* ms_pInstance;
    ....
};
这样就正确了。


但是有一个不方便,就是必须在程序退出的时候手动释放该对象使用的内存!可不可以让它自己释放而不要手动释放?我想到了auto_ptr。
class Singleton
{
    // 私有所有构造函数
public:
    Singleton& GetInstance(void)
    {
        if (ms_apInstance.get() == NULL)
            ms_apInstance.reset(new Singleton());
        return *ms_apInstance;
    }
private:
    static std::auto_ptr<Singleton> ms_apInstance;
    ....
};
该静态对象智能指针会在程序退出main函数后进行析够,删除该对象使用的内存。这样就可以了。


当阅读《Effective C++》的47条时我得到了更简单的实现方式。
class Singleton
{
    // 私有所有构造函数
public:
    Singleton& GetInstance(void)
    {
        static Singleton instance;
        return instance;
    }
    ....
};
上述代码利用“C++函数局部静态对象在函数调用过程中初次碰到对象的定义时被初始化”这一性质。


我想每写一个单键的类时可以写更少的代码,就定义了一个宏:
#define SINGLETON_IMPLEMENT(classname)          \
    public:                                     \
        static classname& GetInstance(void)     \
        {                                       \
            static classname instance;          \
            return instance;                    \
        }
这样我要定义一个单键的类,在类的声明中加入该宏并私有化所有构造函数就可以实现一个单键的类了。