单例模式
一个类 ,从头到尾只 能有一个对象,全世界共用这一个实例。
类的所有成员函数(包括普通成员函数、友元函数)、内部定义的代码,都属于「类的作用域」,在这个作用域内可以直接访问该类对象的 私有(private)和 保护(protected)成员,不受访问权限限制。
类内部 的 static 成员变量 ,只是声明 ,不是定义。
它不占内存 ,必须在类外部全局作用域再定义 一次,才会真正分配空间。
饥汉模式
main()没执行 时,对象已经被创建初始化
全局
cpp
class MyObject
{
private:
int value;
static MyObject objx;
MyObject(int x = 0) :value(x)
{
cout << "Create MyObject:" << this << endl;
}
//无 拷贝构造和 赋值运算符重载
MyObject(const MyObject& it) = delete;
MyObject& operator=(const MyObject& it) = delete;//c++11
public:
~MyObject()
{
cout << "Destroy MyObject:" <<this<< endl;
}
int& Value() { return value; }
const int& Value()const { return value; }
//void Print(cosnt MyObject *const this)
void Print()const//const --->修饰this的指向
{
cout << "value:" << value<< endl;
}
//公共调用同一对象的 接口
static MyObject& getObject()
{
return objx;
}
};
MyObject MyObject::objx(10);
//多线程安全---->只初始化一次
void threadfunc1()
{
MyObject& obj1=MyOject::getObject();
obj1.Print();
}
void threadfunc2()
{
MyObject& obj2=MyOject::getObject();
obj2.Print();
}
int main()
{
MyObject& obj1=MyObject::getObject();//引用绑定
MyObject& obj2 = MyObject::getObject();
cout << "obj1:" << &obj1 << endl;
cout << "obj2:" << &obj2 << endl;
//只创建一个对象
return 0;
}
懒汉模式
-
构造函数私有 ,无参数
-
公共 静态函数 进行初始构造
-
调用时 构造
函数内static对象
cpp
#include <iostream>
#include <thread>
#include <cstdlib>
#include <ctime>
#include <chrono>
using namespace std;
class MyObject
{
private:
int value;
// 构造函数无参!!!(关键)
MyObject() : value(0)
{
cout << "Create MyObject: " << this << endl;
}
MyObject(const MyObject& it) = delete;
MyObject& operator=(const MyObject& it) = delete;
public:
~MyObject()
{
cout << "Destroy MyObject: " << this << endl;
}
int& Value() { return value; }
const int& Value() const { return value; }
void Print() const
{
cout << "value: " << value << endl;
}
// 真正线程安全的单例(无参构造)
static MyObject& getObject()
{
static MyObject objx;
return objx;
}
// 赋值用函数
void setValue(int x)
{
value = x;
}
};
void threadfun1()
{
MyObject& obj1 = MyObject::getObject();
obj1.setValue(10);
obj1.Print();
}
void threadfun2()
{
MyObject& obj2 = MyObject::getObject();
obj2.setValue(20);
obj2.Print();
}
int main()
{
thread tha(threadfun1);
thread thb(threadfun2);
tha.join();
thb.join();
return 0;
}
指针+加锁版本
cpp
#include <mutex>
class MyObject
{
private:
static MyObject* inst;
static std::mutex mtx; // 锁 一份
MyObject() {}
public:
/*
static MyObject* getObject()
{
std::lock_guard<std::mutex> lock(mtx); // 每次都加锁
if (inst == nullptr)
{
inst = new MyObject();
}
return inst;
}*/
static MyObject* getObject()
{
if (inst == nullptr) // 第一次不加锁检查
{
std::lock_guard<std::mutex> lock(mtx);
if (inst == nullptr) // 第二次加锁检查
{
inst = new MyObject();
}
}//lock_guard 锁在进入 {} 时上锁,离开 } 时自动释放。
return inst;
}
};
// 静态成员初始化
MyObject* MyObject::inst = nullptr;
std::mutex MyObject::mtx;
| 老式指针 + 锁 | 函数内 static 对象 | |
|---|---|---|
| 线程安全 | 要自己加锁 | ✅ 天然安全 |
| 效率 | 低 / 一般 | ✅ 最高 |
| 析构 | 不会自动析构 | ✅ 自动析构 |
| 代码 | 复杂 | ✅ 极简 |
| 内存泄漏 | 可能 | ✅ 没有 |
观察者模式
发布、订阅模式
将所有人注册到一个容器中,每个人都有updata()

裸指针
cpp
#include<iostream>
#include<assert.h>
#include<memory>
#include<vector>
#include<time.h>
#include<typeinfo>
#include<list>
#include<algorithm>
#include<string>
using namespace std;
class Subject;
class Observer
{
protected:
string _name;
Subject* _sub;
public:
Observer(const std::string& name,Subject* sub):_name(name),_sub(sub){}
virtual void updata() = 0;
};
class Subject
{
protected:
list<Observer*>_obslist;
bool _is_boss;
string _mess;
public:
Subject() :_is_boss(false), _mess("该干啥就干啥!") {}
~Subject() { removeObserver(); }
void setChanged() { _is_boss = true; _mess = "老板来了!"; }
void clearChanged() { _is_boss = false; _mess = ("该干啥就干啥!"); }
bool hasChanged()const { return _is_boss; }
const string& getMess()const { return _mess; }
void addObserver(Observer* obs)
{
//检查观察者是否重复添加 ----> set
_obslist.push_back(obs);
}
void removeObserver(Observer* obs)
{
auto it = find(_obslist.begin(), _obslist.end(), obs);
if (it != _obslist.end())
{
_obslist.erase(it);
}
}
void removeObserver()
{
_obslist.clear();
}
size_t countObject()const
{
return _obslist.size();
}
virtual void notify() = 0;
};
class Secretary :public Subject
{
public:
void notify()
{
for (auto& obs : _obslist)
{
obs->updata();
}
}
};
class StockObserver :public Observer
{
public:
StockObserver(const std::string& name, Subject* sub):Observer(name,sub){}
void updata()
{
cout << _name << "收到消息" << endl;
if (_sub->hasChanged())
{
cout << _sub->getMess() << "马上关闭炒股软件,装做很认真工作的样子!" << endl;
}
else
{
cout << "老板没来" << _sub->getMess() << endl;
}
}
};
class NBAObserver :public Observer
{
public:
NBAObserver(const std::string& name, Subject* sub) :Observer(name, sub) {}
void updata()
{
cout << _name << "收到消息" << endl;
if (_sub->hasChanged())
{
cout << _sub->getMess() << "马上关闭NBA,装做很认真工作的样子!" << endl;
}
else
{
cout << "老板没来" << _sub->getMess() << endl;
}
}
};
int main()
{
Subject* dwq = new Secretary();
Observer* xs = new NBAObserver("小帅",dwq);
Observer* lm = new NBAObserver("小明", dwq);
Observer* xf = new StockObserver("小芳", dwq);
dwq->addObserver(xs);
dwq->addObserver(lm);
dwq->addObserver(xf);
dwq->notify();
printf("\n=============================================\n");
dwq->setChanged();
dwq->notify();
printf("\n=============================================\n");
dwq->clearChanged();
dwq->notify();
printf("\n=============================================\n");
return 0;
}
智能指针
观察者 ----------->关联发布者
用 weak_ptr ------>观察 二者是否关联,避免造成发布者被删除
cpp
class Subject;
class Observer
{
protected:
string _name;
//shared_ptr<Subject> _sub;
//观察者消失,但生产者依然存在
weak_ptr<Subject> _sub;
public:
Observer(const std::string& name, weak_ptr<Subject> sub) :_name(name), _sub(sub)
{
cout << "Create Observer" << endl;
}
virtual void updata() = 0;
virtual ~Observer()
{
cout << "Destory Observer" << endl;
}
};
class Subject
{
protected:
list<shared_ptr<Observer>>_obslist;
//list<unique_ptr<Observer>>_obslist;
//进行插入 需要扩容 时,底层不确定时 拷贝构造 还是 移动构造
//unique_ptr---->删除 拷贝构造 和 赋值重载
bool _is_boss;
string _mess;
public:
Subject() :_is_boss(false), _mess("该干啥就干啥!")
{
cout << "Create Subject" << endl;
}
void setChanged() { _is_boss = true; _mess = "老板来了!"; }
void clearChanged() { _is_boss = false; _mess = ("该干啥就干啥!"); }
bool hasChanged()const { return _is_boss; }
const string& getMess()const { return _mess; }
void addObserver(shared_ptr<Observer> obs)
{
//检查观察者是否重复添加 ----> set
_obslist.push_back(obs);
}
void removeObserver(shared_ptr<Observer> obs)
{
auto it = find(_obslist.begin(), _obslist.end(), obs);
if (it != _obslist.end())
{
_obslist.erase(it);
}
}
void removeObserver()
{
_obslist.clear();
}
size_t countObject()const
{
return _obslist.size();
}
virtual void notify() = 0;
virtual ~Subject()
{
removeObserver();
cout << "Destory Subject" << endl;
}
};
class Secretary :public Subject
{
public:
Secretary()
{
cout << "Create Secretary" << endl;
}
void notify()
{
for (auto& obs : _obslist)
{
obs->updata();
}
}
~Secretary()
{
cout << "Destory Secretary" << endl;
}
};
class StockObserver :public Observer
{
public:
StockObserver(const std::string& name, weak_ptr<Subject> sub) :Observer(name, sub)
{
cout << "Create StockObserver" << endl;
}
void updata()
{
cout << _name << "收到消息" << endl;
shared_ptr<Subject>sub = _sub.lock();//判断对象是否存活
if (sub == nullptr) { return; }
if (sub->hasChanged())
{
cout << sub->getMess() << "马上关闭炒股软件,装做很认真工作的样子!" << endl;
}
else
{
cout << "老板没来" << sub->getMess() << endl;
}
}
~StockObserver()
{
cout << "Destory StockObserver" << endl;
}
};
class NBAObserver :public Observer
{
public:
NBAObserver(const std::string& name, weak_ptr<Subject> sub) :Observer(name, sub)
{
cout << "Create NBAObserver" << endl;
}
void updata()
{
cout << _name << "收到消息" << endl;
shared_ptr<Subject>sub = _sub.lock();//判断对象是否存活
if (sub == nullptr) { return; }
if (sub->hasChanged())
{
cout << sub->getMess() << "马上关闭NBA,装做很认真工作的样子!" << endl;
}
else
{
cout << "老板没来" << sub->getMess() << endl;
}
}
~NBAObserver()
{
cout << "Destory NBAObserver" << endl;
}
};
int main()
{
shared_ptr<Subject> dwq = make_shared<Secretary> ();
shared_ptr<Observer> xs = make_shared<NBAObserver>("小帅", dwq);
shared_ptr<Observer> lm = make_shared< NBAObserver>("小明", dwq);
shared_ptr<Observer> xf = make_shared<StockObserver>("小芳", dwq);
dwq->addObserver(xs);
dwq->addObserver(lm);
dwq->addObserver(xf);
dwq->notify();
printf("\n=============================================\n");
dwq->setChanged();
dwq->notify();
printf("\n=============================================\n");
dwq->clearChanged();
dwq->notify();
printf("\n=============================================\n");
dwq->removeObserver(xs);
dwq->notify();
printf("\n=============================================\n");
return 0;
}
多线程+门闩+锁
cpp
std::latch my_latch(2);
mutex mtx;
void func_xs(shared_ptr<Subject>dwq)
{
shared_ptr<Observer> xs = make_shared<StockObserver>("小帅", dwq);
dwq->addObserver(xs);
my_latch.count_down();
int n = rand() % 100;
while (n-- != 0)
{
//阻塞
std::this_thread::sleep_for(std::chrono::milliseconds(rand() % 100));
///this_thread::yield(); 主动让度CPU----->就绪态
lock_guard<mutex> locker(mtx);
cout << xs->getname() << endl;
}
}
void func_xm(shared_ptr<Subject>dwq)
{
shared_ptr<Observer> xm = make_shared<StockObserver>("小明", dwq);
dwq->addObserver(xm);
my_latch.count_down();
int n = rand() % 100;
while (n-- != 0)
{
//阻塞
std::this_thread::sleep_for(std::chrono::milliseconds(rand() % 100));
//this_thread::yield(); //主动让度CPU----->就绪态
lock_guard<mutex> locker(mtx);
cout << xm->getname() << endl;
}
}
void func_sec(shared_ptr<Subject>dwq)
{
my_latch.wait();
int n = rand() % 100;
while (n-- != 0)
{
if (rand() % 2 == 0)
{
dwq->setChanged();
}
else
{
dwq->clearChanged();
}
dwq->notify();
lock_guard<mutex> locker(mtx);
cout << "\n======================================\n";
this_thread::sleep_for(chrono::milliseconds( rand() % 100));
}
}
int main()
{
shared_ptr<Subject>dwq = make_shared<Secretary>();
srand(time(nullptr));
std::thread thxs(func_xs, dwq);
std::thread thxm(func_xm, dwq);
std::thread thsec(func_sec, dwq);
cout << "count:" << dwq->countObject() << endl;
thxs.join();
thxm.join();
thsec.join();
return 0;
}