C++11改进观察者模式
2022/4/13 11:12:46
本文主要是介绍C++11改进观察者模式,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
// 用于表明一个类是不允许被拷贝的
#define CANNOT_COPY(Classname) \
private: \
Classname(const Classname&);
// 用于表明一个类是不允许被赋值的
#define CANNOT_ASSIGN(Classname) \
private: \
Classname& operator=(const Classname&);
// 用于表明一个类是不允许被拷贝或赋值的
#define CANNOT_COPY_OR_ASSIGN(Classname) \
private: \
Classname(const Classname&); \
Classname& operator=(const Classname&);
//class NonCopyable
//{
//protected:
// NonCopyable() = default;
// ~NonCopyable() = default;
// NonCopyable(const NonCopyable&) = delete; //禁用复制构造函数
// NonCopyable& operator=(const NonCopyable&) = delete;//禁用赋值构造函数
//};
#pragma once
#include "NonCopyable.h"
#include <map>
template<typename Func>
class Events //: public NonCopyable
{
CANNOT_COPY_OR_ASSIGN(Events)
public:
Events() :m_observerId(0)
{
}
~Events() = default;
//增加+=和-=运算符重载,使用法和C#的event用法接近
int operator +=(Func&& f)
{
return Connect(std::forward<Func>(f));
}
int operator+=(Func& f)
{
return Connect(f);
}
template<typename... Args>
void operator()(Args&&... args)
{
Notify(std::forward<Args>(args)...);
}
Events& operator -=(int key)
{
Disconnect(key);
return *this;
}
void Clear()
{
m_connections.clear();
}
private:
//注册观察者,支持右值引用
int Connect(Func&& f)
{
//return Assgin(f);
return Assgin(std::forward<Func>(f));
}
//注册观察者
int Connect(const Func& f)
{
return Assgin(f);
}
//移除观察者
void Disconnect(int key)
{
m_connections.erase(key);
}
//通知所有的观察者
template<typename... Args>
void Notify(Args&&... args)
{
for (auto& it : m_connections)
{
it.second(std::forward<Args>(args)...);
}
}
//保存观察者并分配观察者的编号
template<typename F>
int Assgin(F&& f)
{
int k = m_observerId++;
m_connections.emplace(k, std::forward<F>(f));
return k;
}
private:
int m_observerId; //观察者对应的编号
std::map<int, Func> m_connections; //观察者列表
};
//测试===================================================
#include <iostream>
#include <functional>
#include "Events.h"
using namespace std;
struct StA
{
int a, b;
void Print(int a, int b)
{
cout <<"StA:"<< "a:" << a << ",b:" << b << endl;
}
};
void Print(int a, int b)
{
cout << "a:" << a << ",b:" << b << endl;
}
void Test1()
{
//Events<std::function<void(int, int)>> event1;
////1.以函数方式注册观察者
//auto key = event1.Connect(Print);
//StA sta;
////2.lamda注册
//auto lambdakey = event1.Connect([/*&sta*/](int a, int b) {
// /* sta.a = a;
// sta.b = b;
// cout << ",,," << a << "," << b << endl;*/
// cout << "a + b = " << a + b << endl;
//});
////3.std::function注册
//std::function<void(int, int)> f = std::bind(&StA::Print, &sta, std::placeholders::_1, std::placeholders::_2);
//event1.Connect(f);
//int a = 1, b = 2;
////4.广播所有观察者
//event1.Notify(a, b);
////5.移除观察者
//event1.Disconnect(key);
////cout << "--------------------------" << endl;
//event1.Notify(a, b);
//cout << "=================================================\n";
//Events<std::function<void()>> event2;
//event2.Connect([]() {
// cout << "hello world" << endl;
//});
//event2.Notify();
}
void Test2()
{
using Deletegate = std::function<void(int, int)>;
using Event1 = Events<Deletegate>;
Event1 event1;
auto key1 = event1 += &Print;
StA t;
auto key2 = event1 += [&t](int a, int b) {
cout << "a+b=" << a + b << endl;;
};
auto key3 = event1 += std::bind(&StA::Print, &t, std::placeholders::_1, std::placeholders::_2);
event1(1,2);
}
void main()
{
//测试1
//Test1();
//委托
Test2();
getchar();
}
这篇关于C++11改进观察者模式的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-05-15PingCAP 黄东旭参与 CCF 秀湖会议,共探开源教育未来
- 2024-05-13PingCAP 戴涛:构建面向未来的金融核心系统
- 2024-05-09flutter3.x_macos桌面os实战
- 2024-05-09Rust中的并发性:Sync 和 Send Traits
- 2024-05-08使用Ollama和OpenWebUI在CPU上玩转Meta Llama3-8B
- 2024-05-08完工标准(DoD)与验收条件(AC)究竟有什么不同?
- 2024-05-084万 star 的 NocoDB 在 sealos 上一键起,轻松把数据库编程智能表格
- 2024-05-08Mac 版Stable Diffusion WebUI的安装
- 2024-05-08解锁CodeGeeX智能问答中3项独有的隐藏技能
- 2024-05-08RAG算法优化+新增代码仓库支持,CodeGeeX的@repo功能效果提升