您的位置:首页 > 编程语言 > C语言/C++

C++单例模式(自动释放实例)

2017-09-26 16:47 357 查看
最基础的实现方法:

#include <iostream>
using namespace std;

class Singleton
{
public:
static Singleton *GetInstance()
{
if (m_Instance == NULL )
{
m_Instance = new Singleton ();
}
return m_Instance;
}

static void DestoryInstance()
{
if (m_Instance != NULL )
{
delete m_Instance;
m_Instance = NULL ;
}
}

// This is just a operation example
int GetTest()
{
return m_Test;
}

private:
Singleton(){ m_Test = 10; }
static Singleton *m_Instance;
int m_Test;
};

Singleton *Singleton ::m_Instance = NULL;

int main(int argc , char *argv [])
{
Singleton *singletonObj = Singleton ::GetInstance();
cout<<singletonObj->GetTest()<<endl;

Singleton ::DestoryInstance();//需要手动释放
return 0;
}


缺点:

1:不仅很丑陋,而且容易出错。因为这样的附加代码很容易被忘记,而且也很难保证在delete之后,没有代码再调用GetInstance函数。

2:在多线程的情况下,就可能创建多个Singleton实例

3:关闭文件,释放外部资源,数据库链接等,那么上面所示的代码无法实现这个要求

多线程改进版本:

#include <iostream>
using namespace std;

class Singleton
{
public:
static Singleton *GetInstance()
{
if (m_Instance == NULL )
{
Lock(); // C++没有直接的Lock操作,请使用其它库的Lock,比如Boost,此处仅为了说明
if (m_Instance == NULL )
{
m_Instance = new Singleton ();
}
UnLock(); // C++没有直接的Lock操作,请使用其它库的Lock,比如Boost,此处仅为了说明
}
return m_Instance;
}

static void DestoryInstance()
{
if (m_Instance != NULL )
{
delete m_Instance;
m_Instance = NULL ;
}
}

int GetTest()
{
return m_Test;
}

private:
Singleton(){ m_Test = 0; }
static Singleton *m_Instance;
int m_Test;
};

Singleton *Singleton ::m_Instance = NULL;

int main(int argc , char *argv [])
{
Singleton *singletonObj = Singleton ::GetInstance();
cout<<singletonObj->GetTest()<<endl;
Singleton ::DestoryInstance();

return 0;
}


分析:

        进行了两次m_Instance == NULL的判断,是借鉴了Java的单例模式实现时,使用的所谓的“双检锁”机制。因为进行一次加锁和解锁是需要付出对应的代价的,而进行两次判断,就可以避免多次加锁与解锁操作,同时也保证了线程安全。

自动销毁实例版本:

#include <iostream>
using namespace std;

class Singleton
{
public:
static Singleton *GetInstance()
{
return m_Instance;
}

int GetTest()
{
return m_Test;
}

private:
Singleton(){ m_Test = 10; }
static Singleton *m_Instance;
int m_Test;

// This is important
class GC
{
public :
~GC()
{
// We can destory all the resouce here
if (m_Instance != NULL )
{
cout<< "Here is the test" <<endl;
delete m_Instance;
m_Instance = NULL ;
}
}
};
static GC gc;
};

Singleton *Singleton ::m_Instance = new Singleton();
Singleton ::GC Singleton ::gc;//必须在类外再次声明

int main(int argc , char *argv [])
{
Singleton *singletonObj = Singleton ::GetInstance();
cout<<singletonObj->GetTest()<<endl;

return 0;
}


说明:

       让这个类自己知道在合适的时候把自己删除。或者说把删除自己的操作挂在系统中的某个合适的点上,使其在恰当的时候自动被执行。

       我们知道,程序在结束的时候,系统会自动析构所有的全局变量。事实上,系统也会析构所有的类的静态成员变量,就像这些静态成员也是全局变量一样。利 用这个特征,我们可以在单例类中定义一个这样的静态成员变量,而它的唯一工作就是在析构函数中删除单例类的实例。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息