C++回顾之static与单例模式
2015-09-15 14:23
351 查看
单例模式是应用最多的一种设计模式,它要求每个类有且只能有一个实例对象,所以用C++设计一个单例模式的方法如下:
1 构造函数声明为私有; 这样就保证了不能随意构造一个对象
2 将拷贝构造函数与等号运算符声明为私有,并不提供他们的实现; 即禁止对象被拷贝。
3 在类中声明一个静态的全局访问接口;
4 声明一个静态的私有实例化指针;
[cpp] view
plaincopy
![](https://code.csdn.net/assets/CODE_ico.png)
![](https://code.csdn.net/assets/ico_fork.svg)
class Singleton
{
public:
//全局访问接口
static Singleton *GetInstance()
{
if( instance_ == NULL )
{
instance_ = new Singleton;
}
return instance_;
}
~Singleton()
{
cout << "~Singleton"<< endl;
}
private:
Singleton(const Singleton& other);
Singleton & operator=(const Singleton & other);
Singleton()
{
cout << "Singleton"<<endl;
}
static Singleton *instance_; //引用性声明
};
Singleton * Singleton::instance_; //定义性声明
int main(void)
{
Singleton *s1 = Singleton::GetInstance();
Singleton *s2 = Singleton::GetInstance(); //s2的地址等于s1,即指向同一对象
//Singleton s3(*s1); //既然是单例模式,是不允许被拷贝的。编译会出错
return 0;
}
上面就是单例类模式的C++实现,但是上述代码还有一个缺陷:单例类中申请的一些资源没有被释放,如instance_指向的空间没有被回收。一共有两种解决方式:
第一种解决方式:
[cpp] view
plaincopy
![](https://code.csdn.net/assets/CODE_ico.png)
![](https://code.csdn.net/assets/ico_fork.svg)
class Singleton
{
...
//提供一个回收接口,在应用中显示调用回收资源
static void Free()
{
delete instance_;
}
....
};
int main()
{
...
Singleton::Free(); //要显示调用进行资源回收
}
这种方式虽然能实现功能,但是不太方便,每次都要手动回收资源,这是它的缺点。
第二种解决方式:
[cpp] view
plaincopy
![](https://code.csdn.net/assets/CODE_ico.png)
![](https://code.csdn.net/assets/ico_fork.svg)
class Singleton
{
...
public:
class Garbo //资源回收机制
{
public:
~Garbo()
{
if( Singleton::instance_ != NULL )
{
delete instance_;
}
}
};
...
private:
...
static Garbo garbo_; //引用性声明
};
Singleton::Garbo Singleton::garbo_;//定义性声明
这种方式提供的处理方式显然要比第一种方式来的要便捷,因为它依靠内部提供的Garbo嵌套类来提供服务,当Singleton类生命周期结束时,Garbo的类对象garbo_也要销毁,它将调用析构函数,而在析构函数中又自动地释放了Singleton单例类申请的一些资源,这种实现就比较智能化。不需要手动释放资源。这是它的优势。
下面提供另一种实现C++单例类模式的方法:
[cpp] view
plaincopy
![](https://code.csdn.net/assets/CODE_ico.png)
![](https://code.csdn.net/assets/ico_fork.svg)
class Singleton
{
public:
static Singleton& GetInstance()
{
static Singleton instance_; return instance_;
}
~Singleton()
{
cout << "~Singleton"<<endl;
}
private:
Singleton()
{
cout << "Singleton "<<endl;
}
Singleton(const Singleton &other);
Singleton & operator=(const Singleton &other);
};
这种实现方式利用了static修改函数内部的变量,当第一次调用GetInstance函数时,系统将构造一个Singleton对象,在后续再次调用这个函数时,系统不再执行这个语句,也就不会再构造Singleton类对象了,而直接返回instance_本身。另外,当Singleton类对象生命周期结束时,对象会自动调用析构函数销毁,这里也就不存在申请资源之类的了,需要注意的是GetInstance()函数返回的是引用,这样就不会调用拷贝构造函数了,使用时也应该声明Singleton的引用,如下:
[cpp] view
plaincopy
![](https://code.csdn.net/assets/CODE_ico.png)
![](https://code.csdn.net/assets/ico_fork.svg)
int main()
{
Singleton &s1 = Singleton::GetInstance();
Singleton &s2 = Singleton::GetInstance(); //s1与s2是同一对象的引用
return 0;
}
1 构造函数声明为私有; 这样就保证了不能随意构造一个对象
2 将拷贝构造函数与等号运算符声明为私有,并不提供他们的实现; 即禁止对象被拷贝。
3 在类中声明一个静态的全局访问接口;
4 声明一个静态的私有实例化指针;
[cpp] view
plaincopy
![](https://code.csdn.net/assets/CODE_ico.png)
class Singleton
{
public:
//全局访问接口
static Singleton *GetInstance()
{
if( instance_ == NULL )
{
instance_ = new Singleton;
}
return instance_;
}
~Singleton()
{
cout << "~Singleton"<< endl;
}
private:
Singleton(const Singleton& other);
Singleton & operator=(const Singleton & other);
Singleton()
{
cout << "Singleton"<<endl;
}
static Singleton *instance_; //引用性声明
};
Singleton * Singleton::instance_; //定义性声明
int main(void)
{
Singleton *s1 = Singleton::GetInstance();
Singleton *s2 = Singleton::GetInstance(); //s2的地址等于s1,即指向同一对象
//Singleton s3(*s1); //既然是单例模式,是不允许被拷贝的。编译会出错
return 0;
}
上面就是单例类模式的C++实现,但是上述代码还有一个缺陷:单例类中申请的一些资源没有被释放,如instance_指向的空间没有被回收。一共有两种解决方式:
第一种解决方式:
[cpp] view
plaincopy
![](https://code.csdn.net/assets/CODE_ico.png)
class Singleton
{
...
//提供一个回收接口,在应用中显示调用回收资源
static void Free()
{
delete instance_;
}
....
};
int main()
{
...
Singleton::Free(); //要显示调用进行资源回收
}
这种方式虽然能实现功能,但是不太方便,每次都要手动回收资源,这是它的缺点。
第二种解决方式:
[cpp] view
plaincopy
![](https://code.csdn.net/assets/CODE_ico.png)
class Singleton
{
...
public:
class Garbo //资源回收机制
{
public:
~Garbo()
{
if( Singleton::instance_ != NULL )
{
delete instance_;
}
}
};
...
private:
...
static Garbo garbo_; //引用性声明
};
Singleton::Garbo Singleton::garbo_;//定义性声明
这种方式提供的处理方式显然要比第一种方式来的要便捷,因为它依靠内部提供的Garbo嵌套类来提供服务,当Singleton类生命周期结束时,Garbo的类对象garbo_也要销毁,它将调用析构函数,而在析构函数中又自动地释放了Singleton单例类申请的一些资源,这种实现就比较智能化。不需要手动释放资源。这是它的优势。
下面提供另一种实现C++单例类模式的方法:
[cpp] view
plaincopy
![](https://code.csdn.net/assets/CODE_ico.png)
class Singleton
{
public:
static Singleton& GetInstance()
{
static Singleton instance_; return instance_;
}
~Singleton()
{
cout << "~Singleton"<<endl;
}
private:
Singleton()
{
cout << "Singleton "<<endl;
}
Singleton(const Singleton &other);
Singleton & operator=(const Singleton &other);
};
这种实现方式利用了static修改函数内部的变量,当第一次调用GetInstance函数时,系统将构造一个Singleton对象,在后续再次调用这个函数时,系统不再执行这个语句,也就不会再构造Singleton类对象了,而直接返回instance_本身。另外,当Singleton类对象生命周期结束时,对象会自动调用析构函数销毁,这里也就不存在申请资源之类的了,需要注意的是GetInstance()函数返回的是引用,这样就不会调用拷贝构造函数了,使用时也应该声明Singleton的引用,如下:
[cpp] view
plaincopy
![](https://code.csdn.net/assets/CODE_ico.png)
int main()
{
Singleton &s1 = Singleton::GetInstance();
Singleton &s2 = Singleton::GetInstance(); //s1与s2是同一对象的引用
return 0;
}
相关文章推荐
- C++学习之分解质因数
- C语言学习手记-一元二次函数解法
- C++ Primer Plus(第六版)--学习杂记(第三章)
- C++实现《面向对象之设计模式——单身模式》
- 程序调试VC++ 6.0
- loadrunner icrosoft Visual c++2005 sp1运行时组件,就会提示命令行选项语法错误,键入“命令/?”
- 为什么要用C++编写服务端程序?
- c/c++ 对于浮点型的判断
- 用C++品尝Vista美味:界面的毛玻璃效果——涨姿势
- C++基础知识总结-类的基本知识
- C语言link过程详解(多文件编译过程)
- C++程序设计实践题1
- c++builder6.0 mdi窗体+自定义子窗体
- C++如何返回函数指针
- qt4编译c++11文件
- C++中虚函数的实现原理
- C++程序中尽可能使用const
- 【C/C++学院】0804-C语言和设计模式(继承、封装、多态)
- 二进制值和十六进制字符串相互转换的C++代码
- c++ primer 学习笔记-第十四章