欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C++模板学习之单例类模板问题

程序员文章站 2022-10-27 16:21:36
单例模式 存在的问题 需求:在架构设计时,一些类在整个声明周期中最多只能有一个对象存在。那么我们如何定义一个类,使得这个类最多只能创建一个对象呢 单例模式 要控制类的对象数目,必须隐藏构造函数 定义...

单例模式 存在的问题

需求:在架构设计时,一些类在整个声明周期中最多只能有一个对象存在。那么我们如何定义一个类,使得这个类最多只能创建一个对象呢

单例模式

要控制类的对象数目,必须隐藏构造函数 定义一个静态对象指针instance并初始化为null,当需要创建对象时,先判断instance的值:

a) 当instance为空值时:创建对象,并用instance标记

b) 当instance为非空值时,返回instance标记的对象。

示例代码:单例模式初探

#include 
#include 

using namespace std;

class sobject
{
 static sobject* c_instance;

 sobject(const sobject&);
 sobject& operator= (const sobject&);

 sobject()
 {
 }
public:
 static sobject* getinstance();

 void print()
 {
  cout << "this = " << this << endl;
 }
};

sobject* sobject::c_instance = null;

sobject* sobject::getinstance()
{
 if( c_instance == null )
 {
  c_instance = new sobject();
 }

 return c_instance;
}

int main()
{
 sobject* s = sobject::getinstance();
 sobject* s1 = sobject::getinstance();
 sobject* s2 = sobject::getinstance();

 s->print();
 s1->print();
 s2->print();

 return 0;
}

输出结果:
this = 0x9674008
this = 0x9674008
this = 0x9674008

我们发现,无论创建多少个对象,实际对象只有一个!

存在的问题

必须定义静态成员变量c_instance 必须定义静态成员函数getinstance()

问题:如何解决这个问题呢

我们可以将单例模式相关的代码抽取出来,开发单例类模板。当需要使用单例类模板时,可以申请成为单例类模板的友元类。这样就可以直接成为单例模式了。

示例代码:

//singleton.h
#ifndef _singleton_h_
#define _singleton_h_

template
< typename t >
class singleton
{
 static t* c_instance;
public:
 static t* getinstance();
};

template
< typename t >
t* singleton::c_instance = null;

template
< typename t >
t* singleton::getinstance()
{
 if( c_instance == null )
 {
  c_instance = new t();
 }

 return c_instance;
}


#endif


//main.cpp
#include 
#include 
#include "singleton.h"
using namespace std;

class sobject
{
 friend class singleton; // 当前类需要使用单例模式

 sobject(const sobject&);
 sobject& operator= (const sobject&);

 sobject()
 {
 }
public:
 void print()
 {
  cout << "this = " << this << endl;
 }
};

int main()
{
 sobject* s = singleton::getinstance();
 sobject* s1 = singleton::getinstance();
 sobject* s2 = singleton::getinstance();

 s->print();
 s1->print();
 s2->print();

 return 0;
}