对单例模式的一个简单思考

测试代码以下:ios

#include <iostream>

class TestSingleton
{
public:
    ~TestSingleton()
    {
        std::cout << "TestSingleton " << m_i << " destructor\n";
    }
    static TestSingleton& getInstance(int i)
    {
        static TestSingleton ts(i);
        return ts;
    }
private:
    TestSingleton(int i):m_i(i)
    {
        std::cout << "TestSingleton " << m_i << " constructor\n";
    }
    int m_i;

};

int main()
{
    TestSingleton& ts1 = TestSingleton::getInstance(1);
    TestSingleton& ts2 = TestSingleton::getInstance(2);
}

代码很简单,最终的结果怎样呢?函数

我本来觉得1和2都会输出的,由于两次分别调用getInstance时用的是不同的参数,因此应该会实例出两个不同的TestSingleton对象吧,最终的结果和我料想的有所不一样:测试

image

只构造出了参数为1的singleton对象,并没与改造出参数为2的对象,这是为何呢?仔细思考了一下,而后就顿悟了,哎,缘由仍是出了对static关键字的理解不深,这么快就忘记了。spa

在函数体中,若是声明了一个static变量,无论进入这个函数多少次,该static变量只会被初始化一次。设计

因此当我第二次调用getInstance函数时,进入getInstance后直接就跳过了TestSingleton的初始化语句,也就是TestSingleton的构造函数,所以最终获得的TestSinglon对象和上次的是同一个。我打断点调试的时候发现确实如此。调试

从这里我收获了一个小小的道理,单例模式的构造函数不该该传参,若是须要传参的话,这个类就应该被设计为普通类。由于若是须要传参的话,就很根据不一样的参数生成不一样的类的实例,与单例类“一个类只存在一个对象”的设定不符。code


其实道理与下面这个是类似的。对象

void fun(int i)
{
    static int m(i);
    std::cout << m << "\n";
}

int main()
{
    fun(1);
    fun(2);
}

最终两次的输出结果依然都是1,由于m只被初始化一次。blog

void fun(int i)
{
    static int m = i;
    std::cout << m << "\n";
}

int main()
{
    fun(1);
    fun(2);
}

最终的输出仍然为两个1,这段和上段代码有点相似于 类的拷贝构造和赋值构造 都是”构造函数”。get

void fun(int i)
{
    static int m;
    m = i;
    std::cout << m << "\n";
}

int main()
{
    fun(1);
    fun(2);
}

这样的话输出结果就变成一个1和一个2了。

相关文章
相关标签/搜索