存档

文章标签 ‘设计模式’

从单例模式谈起(一)

2019/04/08 5,504

单例模式可能是大家最为熟知的一种设计模式,本身没什么好谈的。但是在 C++ 中,由单例模式可以引出一系列的问题,可能会比较有意思,这里探讨一下。

常见的简单实现

1.使用 static 实现

class S1 {
    public:
        static S1& GetInstance() {
            static S1 s;
            return s;
        }   
        void fun() {}

    private:
        S1(){cout<<"S1 inited"<<endl;}
        S1(const S1&) = delete;
        S1& operator=(const S1&) = delete;
};

class S2{ 
    public:
        static S2& GetInstance(){
            return s;
        }   
        void fun(){}
    private:
        S2(){cout<<"S2 inited"<<endl;}
        //...
    private:
        static S2 s;
};
S2 S2::s;

其中 S2 是要避免的。因为 1. 类的静态成员变量的初始化时间一般早于 main 函数 2. 如果静态成员的初始化里调用了其它类,可能出现未定义的错误。

2.使用指针判断是否初始化

class S3{
    public:
        static S3& GetInstance(){
            if(s == 0)
                s = new S3();
                 return *s;
        }

    private:
        S3(){}
        static S3 *s;
};

这两种方式在单线程程序中使用都是可以的,但如果在多线程中,就会出现问题。

Magic Static

对于 S1 要注意, C++ 局部静态变量的初始化可能不是线程安全的 , 这就是 Magic Static ,是指 返回一个静态局部变量的引用 的用法,在某些情况下,如S1 可能会被编译器这样解析:

继续阅读