单例模式的优点和缺点:
优点:
- 节约内存:保证内存里只有一个实例,减少内存的开销;
- 资源共用:可以避免对资源的多重占用;
- 访问自由:调用端可以随时访问单例类中的资源,起到优化和共享资源。
缺点:
- 扩展困难:单例类中的构造函数,其访问权限都是private,导致无法被继承;一般没有多余接口,如果需要接口扩展,只能修改单例类代码,别无他法,违背了设计七大原则中的【开闭原则】;
- 不利于代码调试:在并发测试中,如果单例模式没有执行完成,不能再生成一个新的对象;
- 违背单一指责原则:功能代码写在一个类中,如果功能设计不合理,则很容易违背【单一职责原则】。
单例模式的实现 :
懒汉式单例:
类声明:
class LazySingleton
{
public:
~LazySingleton();
public:
/*
* 创建实例对象
*/
static LazySingleton* getInstance();
/*
* 成员函数
*/
void printfInfo()
{
std::cout << "I'm LazyInstance!" << std::endl;
}
/*
* 回收内存,销毁对象实例
*/
void destoryInstance();
private:
LazySingleton();
//~LazySingleton();
private:
static /*volatile*/ LazySingleton *m_instance;
};
?说明:
- 构造函数访问权限一定是private的;
- 析构函数访问权限可以public,也可以private;
- 定义一个private的静态对象指针变量;
- 通过public的静态成员函数去初始化该对象指针,并返回获得该指针变量;
- static成员函数,只能访问static成员变量;static成员变量也可以被no static成员函数访问。
?类实现:
/*volatile*/ LazySingleton* LazySingleton::m_instance = NULL;//静态成员变量,必须在类声明的外部初始化定义
LazySingleton::LazySingleton()
{
std::cout << "LazySingleton::LazySingleton()..." << std::endl;
}
LazySingleton::~LazySingleton()
{
std::cout << "LazySingleton::~LazySingleton()..." << std::endl;
}
LazySingleton* LazySingleton::getInstance()
{
if (NULL == m_instance)
{
m_instance = new LazySingleton();
std::cout << "Creat Object Instance..." << std::endl;
}
return m_instance;
};
void LazySingleton::destoryInstance()
{
if (m_instance)
{
std::cout << "Destory Object Instance..." << std::endl;
delete m_instance;
m_instance = NULL;
}
};
说明:
- ?类的静态成员变量的初始化工作,必须放在类声明的外部;
- ?对象指针创建以后,内存中有且只有一个存在。需要再次被创建,除非对已有对象指针进行销毁。
int main()
{
/*
* 单例对象的创建、调用和销毁
*/
std::cout << "------单例对象的创建、调用和销毁之【方法一】------" << std::endl;
LazySingleton::getInstance()->printfInfo();
LazySingleton::getInstance()->destoryInstance();
std::cout << std::endl << std::endl;
std::cout << "------单例对象的创建、调用和销毁之【方法二】------" << std::endl;
LazySingleton* pInstance = LazySingleton::getInstance();
if (pInstance)
{
pInstance->printfInfo();
delete pInstance;
pInstance = NULL;
}
system("pause");
return 0;
}
说明:
- 单例模式对象创建:在第一次调用getInstance方法时;
- 析构函数访问权限:如果调用destoryInstance方法销毁指针,可声明为private;如果使用delete销毁,则声明为public。
饿汉式单例:
类声明:
class HungrySingleton
{
public:
/*
* 获取对象
*/
static HungrySingleton& getInstance();
/*
* 成员函数
*/
void printfInfo()
{
std::cout << "I'm HungryInstance!" << std::endl;
}
private:
HungrySingleton();
~HungrySingleton();
static HungrySingleton m_instance;//静态对象,在程序运行时被立即初始化
};
说明:?
- 饿汉式单例在类创建的同时就已经创建好一个静态的对象供系统使用,以后不再改变,所以是线程安全的,可以直接用于多线程而不会出现问题。
类实现:
HungrySingleton HungrySingleton::m_instance;//注意:不可缺少
HungrySingleton::HungrySingleton()
{
std::cout << "HungrySingleton::HungrySingleton()..." << std::endl;
}
HungrySingleton::~HungrySingleton()
{
std::cout << "HungrySingleton::~HungrySingleton()..." << std::endl;
}
HungrySingleton& HungrySingleton::getInstance()
{
return m_instance;
}
说明:
int main()
{
std::cout << "------单例对象的创建、调用和销毁之【方法一】------" << std::endl;
HungrySingleton::getInstance().printfInfo();
return 0;
}
|