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改进观察者模式的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程