单例模式:是指在内存中值创建一个类的对象,让所有需要调用的地方都共享这个单例对象
二、饿汉模式实现 1.优缺点:单例模式有两种实现方式:
饿汉模式:是类创建的时候,就创建好了实例对象
懒汉模式:需要的时候再去创建
优点:因为饿汉模式是提前创建好对象,所以是线程安全的
缺点:不管系统需不需要这个创建对象,它都会创建出对象,所以会造成内存空间的浪费。
#include
using namespace std;
//饿汉模式
class Singleton {
private:
Singleton() {
cout << "创建了一个单例对象" << endl;
}
static Singleton* instance; //静态数据成员在类内声明
~Singleton() {
cout << "销毁了一个单例对象" << endl;
}
public:
static Singleton* getinstance() {
return instance;
}
static void destroy() { //需要自定义一个销毁函数
cout << "销毁了一个单例对象(自定义销毁)" << endl;
delete instance;
}
};
Singleton* Singleton::instance = new Singleton(); //静态数据成员在类外进行定义初始化
int main() {
cout << "now we get the instance" << endl;
Singleton* s1 = Singleton::getinstance();
Singleton* s2 = Singleton::getinstance();
Singleton* s3 = Singleton::getinstance();
cout << s1 << endl;
cout << s2 << endl;
cout << s3 << endl; //三个输出的地址都是一样的,即当创建一个对象后,再次创建对象时地址是一样的,说明单例模式返回的是同一个对象
cout << "now we destroy the instance" << endl;
Singleton::destroy();
//饿汉模式,从输出可以看出,虽然代码中写了s1,s2,s3,但是程序只创建了一个对象。
return 0;
}
运行结果如下:
优点:系统需要的时候再去创建,不会存在内存浪费问题 所以在创建对象的时候需要加锁,来避免错误的产生。
缺点:当系统中有多个线程运行时,若同时检测到未创建实例对象,则这两个线程都会创建对象,那么此时就不再是单例模式,报错,所以存在线程安全问题。
示例中模拟随机多线程实现,通过锁来解决懒汉模式下的存在的线程安全问题。
//懒汉模式 需要考虑线程安全问题
#include
#include
#include
#include
#include
#include
using namespace std;
mutex my_mutex; //创建一个线程
class Singleton {
private:
Singleton() {
cout << "创建了一个单例对象" << endl;
}
Singleton(const Singleton&);
Singleton& operator=(const Singleton&);
~Singleton() {
cout << "销毁了一个单例对象" << endl;
}
static Singleton *instance;
public:
static Singleton *getinstance() {
if (instance == NULL) {
my_mutex.lock();
if (instance == NULL) {
instance = new Singleton();
}
}
return instance;
}
static void destroy() {
cout << "销毁了一个单例对象(自己定义)" << endl;
delete instance;
}
};
Singleton* Singleton::instance = NULL;
void func1() {
int num = rand() % 10;
Sleep(num * 10);
cout << "另外1个线程" << endl;
Singleton* s1 = Singleton::getinstance();
cout <<s1 << endl;
Singleton::destroy();
return;
}
void func2() {
int num = rand() % 10;
Sleep(num * 10);
cout << "另外2个线程" << endl;
Singleton* s2 = Singleton::getinstance();
cout << s2 << endl;
Singleton::destroy();
return;
}
void func3() {
int num = rand() % 10;
Sleep(num * 10);
cout << "另外3个线程" << endl;
Singleton* s3 = Singleton::getinstance();
cout << s3 << endl;
Singleton::destroy();
return;
}
int main() {
cout << "now we get the instance" << endl;
thread other1(func1);
thread other2(func2);
thread other3(func3);
cout << "now we destroy the instance" << endl;
other1.join();
other2.join();
other3.join();
Singleton::destroy();
}
运行结果:
(1)表示文件系统的类,一个 *** 作系统一定只是一个文件系统,因此文件系统的类的示例有且仅有一个。
(2)打印机打印程序的实例,通过单例模式避免两个打印作业同时输出到打印机。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)