zoukankan      html  css  js  c++  java
  • 单例模式

       在编写代码project时,非常多时候我们须要对象的唯一性,即整个project或项目中仅仅须要类的一个实例。能够通过设计模式的单例模式来实现。

    下面是我用c++实现的两种方式:

    另外一种较第一种代码逻辑稍简单些。

    class Singlton
    {
    private:
    <span style="white-space:pre">	</span>int m_nNum;
    <span style="white-space:pre">	</span>static Singlton* m_pSinglton;
    <span style="white-space:pre">	</span>Singlton(int num)
    <span style="white-space:pre">	</span>{
    <span style="white-space:pre">		</span>m_nNum = num;
    <span style="white-space:pre">		</span>std::cout<<"construct Singlton!"<<endl;
    <span style="white-space:pre">	</span>}
    public:
    <span style="white-space:pre">	</span>static Singlton* getInstance()
    <span style="white-space:pre">	</span>{
    <span style="white-space:pre">		</span>if (m_pSinglton == NULL)
    <span style="white-space:pre">		</span>{
    <span style="white-space:pre">			</span>m_pSinglton = new Singlton(1);
    <span style="white-space:pre">		</span>}
    <span style="white-space:pre">		</span>return m_pSinglton;
    <span style="white-space:pre">	</span>}
    <span style="white-space:pre">	</span>
    };
    Singlton* Singlton::m_pSinglton = new Singlton(1);
    int main(int argc, char *argv[])
    {
    <span style="white-space:pre">	</span>QCoreApplication a(argc, argv);
    <span style="white-space:pre">	</span>Singlton::getInstance();
    <span style="white-space:pre">	</span>return a.exec();
    }

    这样的方法是通过静态成员变量和静态成员函数来实现的。该代码有一点须要注意:

    1、Singlton* Singlton::m_pSinglton = new Singlton(1);    静态成员变量能用私有构造函数来构造吗?私有的为什么有訪问权限。

    要理解这个问题首先要了解訪问类的成员有两种方式:(1)通过this指针(2)通过作用域。处于作用域中的能够訪问作用域中的全部成员。如:

    class Test
    {
    private:
      int num;
    public:
    void Init();
    };
    //declare.cpp
    include"declare.h"
    void Test::Init()
    {
      num=1;//num也是Test的private成员
    }
    类似于上面的代码,静态成员变量 Singlton::m_pSinglton 处于Singlton作用域中。所以能訪问私有构造函数。

    另外一种方法使用了局部静态变量方式实现

    class Singlton
    {
    private:
    	Singlton()
    	{
    		std::cout<<"construct Singlton!"<<endl;
    	}
    public:
    	static Singlton* getInstance()
    	{
    		static Singlton m_pSinglton;
    		return &m_pSinglton;
    	}
    };
    
    int main(int argc, char *argv[])
    {
    	QCoreApplication a(argc, argv);
    	Singlton::getInstance();
    	return a.exec();
    }

    因为局部静态变量的作用域是整个生命周期,所以能够利用这样的方式创建单例,较第一种更为简单。

    可是以上两种方式都不是线程安全的。

    假设有多个线程同一时候调用getInstance,可能会创建出多个实例。违背了单例模式。当然能够使用线程同步机制(如进行加锁解锁),可是这些机制速度慢开销大,能够考虑使用原子操作来弥补这一缺陷。

    兴许会加入通过原子操作来实现多线程线下线程安全问题。

  • 相关阅读:
    Monkey学习笔记(一)
    10.18 nslookup:域名查询工具
    10.22 tcpdump:监听网络流量
    10.22 tcpdump:监听网络流量
    Linux运维常见笔试题(选择题)
    Linux运维40道精华题
    LeetCode Isomorphic Strings 对称字符串
    LeetCode 3Sum Closest 最近似的3sum(2sum方法)
    博弈的图论模型——必败态与核
    威佐夫博弈(证明)
  • 原文地址:https://www.cnblogs.com/wgwyanfs/p/6789071.html
Copyright © 2011-2022 走看看