目录
1.如何提供一个全局变量来记录函数调用次数呢?
2.1饿汉模式
2.2懒汉模式
2.2.1实现一个内嵌垃圾回收类
懒汉的另一种写法
1.如何提供一个全局变量来记录函数调用次数呢?
声明定义分离
func.h
extern int Count ;//声明
func.cpp
#include "func.h" int Count = 0;//定义 void func() { for (int i = 10; i > 0; i--) { ++Count; } }
test.cpp
#include "func.h" int main() { func(); cout << "count:" << Count << endl; return 0; }
2.单例模式
定义:一个类只能创建一个对象,即单例模式,该模式可以保证系统中该类只有一个实例,并提供一个访问它的全局访问(GetInstance),该实例被所有程序模块共享(所以文件都可以访问)。
2.1饿汉模式
饿汉模式:饿了随时准备吃,在调用之前就定义好了
singleton.h
- 单例模式只有一个对象:那么构造函数私有且声明一个静态对象(类::静态对象函数可以访问),再除了singleton.h的任意一个文件定义,再使用一个静态成员去取那个唯一的对象就达到需求;
- 单例不可以拷贝,所有拷贝构造防拷贝;赋值重载不需要,因为赋值重载需要两个定义的对象
//饿汉模式 class GetInformation { public: static GetInformation& GetInstance() { return instance; } void Add(const int n)//对象私有+需要一个接口函数 { _count += n; } int GetConut()//个数 { return _count; } GetInformation(const GetInformation& instance)=delete;//单例不能拷贝,防拷贝 private: GetInformation(int n=0) :_count(n) {} int _count; static GetInformation instance;//类里面都是声明 };
singleton.cpp
#include "singleton.h" GetInformation GetInformation::instance(0);//定义,静态成员可以用类名+::访问 void func() { for (int i = 10; i > 0; i--) { GetInformation::GetInstance().Add(1); } }
test.cpp
#include "singleton.h" int main() { func(); cout << "GetCount:" << GetInformation::GetInstance().GetConut() << endl; return 0; }
执行结果
2.2懒汉模式
懒汉模式:在第一次调用时才定义
singleton.h
- 单例模式只有一个对象:那么构造函数私有且声明一个静态对象指针(类::静态对象函数可以访问),再除了singleton.h的任意一个文件定义为nullptr,在第一次调用是new一个对象;再使用一个静态成员去取那个唯一的对象就达到需求
- 单例不可以拷贝,所有拷贝构造防拷贝;赋值重载不需要,因为赋值重载需要两个定义的对象
//懒汉模式 class GetInformation { public: static GetInformation& GetInstance() { if (instance == nullptr)//第一次调用new一个对象处理 { instance = new GetInformation; } return *instance; } void Add(const int n) { instance->_count += n; } int GetConut() { return instance->_count; } GetInformation(const GetInformation& instance) = delete;//防拷贝 GetInformation(int n = 0) :_count(n) {} private: int _count; static GetInformation* instance;类里面都是声明 };
singleton.cpp
#include "singleton.h" GetInformation* GetInformation::instance=nullptr;//定义,静态成员可以用类名+::访问 void func() { for (int i = 10; i > 0; i--) { GetInformation::GetInstance().Add(1); } }
test.cpp
#include "singleton.h" int main() { func(); cout << "Getount:" << GetInformation::GetInstance().GetConut() << endl; return 0; }
执行结果
2.2.1实现一个内嵌垃圾回收类
- 在懒汉模式中声明周期结束,只有一个对象指针,new出来的空间没有得到释放
- 一般懒汉的单例对象,不需要回收,因为进程正常结束,资源都会还给系统,这个对象只有一个系统自动回收也没什么问题, 但是如果在单例对象释放析构时,有一些要完成的动作,比如要记录日志等等。那么可以考虑搞一个类似下面的回收类帮助去完成这个事情.
singleton.h
- 生命周期结束,内嵌垃圾回收类对象自动析构
//懒汉模式 class GetInformation { public: static GetInformation& GetInstance() { if (instance == nullptr) { instance = new GetInformation; } return *instance; } GetInformation(const GetInformation& instance) = delete; GetInformation(int n = 0) :_count(n) {} // 实现一个内嵌垃圾回收类 class CGarbo { ~CGarbo() { if (instance != nullptr) { delete instance; } } private: }; private: static CGarbo _CGarbo; int _count; static GetInformation* instance;//声明 };
singleton.cpp
#include "singleton.h" GetInformation* GetInformation::instance=nullptr;//定义,静态成员可以用类名+::访问 GetInformation::CGarbo _CGarbo;//垃圾回收定义
懒汉模式和饿汉模式的优缺点
懒汉的另一种写法
- 在C++11更推荐这种懒汉写法,它解决了懒汉的缺点
//饿汉模式
class GetInformation
{
public:
static GetInformation& GetInstance()
{
// C++98 中多线程调用时,static sInst对象构造初始化并不能保证下线程安全
// C++11 优化了这个问题,C++11中static sInst对象构造初始化是线程安全的
static GetInformation instance;
return instance;
}
void Add(const int n)
{
_count += n;
}
int GetConut()
{
return _count;
}
GetInformation(const GetInformation& instance)=delete;
private:
GetInformation(int n=0)
:_count(n)
{}
int _count;
};