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


    测试代码如下:

    #include <iostream>
    
    class TestSingleton
    {
    public:
        ~TestSingleton()
        {
            std::cout << "TestSingleton " << m_i << " destructor
    ";
        }
        static TestSingleton& getInstance(int i)
        {
            static TestSingleton ts(i);
            return ts;
        }
    private:
        TestSingleton(int i):m_i(i)
        {
            std::cout << "TestSingleton " << m_i << " constructor
    ";
        }
        int m_i;
    
    };
    
    int main()
    {
        TestSingleton& ts1 = TestSingleton::getInstance(1);
        TestSingleton& ts2 = TestSingleton::getInstance(2);
    }

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

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

    image

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

    在函数体中,如果声明了一个static变量,不管进入这个函数多少次,该static变量只会被初始化一次。

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

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


    其实道理与下面这个是相似的。

    void fun(int i)
    {
        static int m(i);
        std::cout << m << "
    ";
    }
    
    int main()
    {
        fun(1);
        fun(2);
    }

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

    void fun(int i)
    {
        static int m = i;
        std::cout << m << "
    ";
    }
    
    int main()
    {
        fun(1);
        fun(2);
    }

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

    void fun(int i)
    {
        static int m;
        m = i;
        std::cout << m << "
    ";
    }
    
    int main()
    {
        fun(1);
        fun(2);
    }

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

  • 相关阅读:
    POJ2175 Evacuation Plan
    POJ3252 Round Numbers
    POJ2115 C Looooops
    POJ3422 Kaka's Matrix Travels
    POJ1659 Frogs' Neighborhood
    POJ2635 The Embarrassed Cryptographer
    POJ3436 ACM Computer Factory
    FZU1607 Greedy division
    EOJ440 Buying Feed
    POJ2135 Farm Tour
  • 原文地址:https://www.cnblogs.com/XiaoXiaoShuai-/p/12359174.html
Copyright © 2020-2023  润新知