NonCopyable.h:不可复制机类
#pragma once
class NonCopyable
{
protected:
NonCopyable() = default;
~NonCopyable() = default;
// 禁用复制构造
NonCopyable(const NonCopyable&) = delete;
// 禁用赋值构造
NonCopyable& operator = (const NonCopyable&) = delete;
};
AOP.h:AOP实现
#pragma once
#include <iostream>
using namespace std;
#define HAS_MEMBER(member) \
template<typename T,typename...Args> struct has_member_##member\
{\
private:\
template<typename U> static auto Check(int)->decltype(declval<U>().member(declval<Args>()...),true_type());\
template<typename U> static false_type Check(...);\
public:\
enum{value=is_same<decltype(Check<T>(0)),true_type>::value};\
};\
HAS_MEMBER(Foo)
HAS_MEMBER(Before)
HAS_MEMBER(After)
#include "NonCopyable.h"
template<typename Func,typename...Args>
struct Aspect :NonCopyable
{
Aspect(Func&& f) :m_func(forward<Func>(f))
{
}
template<typename T>
typename enable_if<has_member_Before<T,Args...>::value&&has_member_After<T,Args...>::value > ::type Invoke(Args&&...args,T&& aspect)
{
aspect.Before(forward<Args>(args)...); //核心逻辑之前的切面逻辑
m_func(forward<Args>(args)...); //核心逻辑
aspect.After(forward<Args>(args)...); //核心逻辑之后的切面逻辑
}
template<typename T>
typename enable_if<has_member_Before<T,Args...>::value&&!has_member_After<T,Args...>::value>::type Invoke(Args&&...args,T&& aspect)
{
aspect.Before(forward<Args>(args)...); //核心逻辑之前的切面逻辑
m_func(forward<Args>(args)...); //核心逻辑
}
template<typename T>
typename enable_if<!has_member_Before<T,Args...>::value && has_member_After<T,Args...>::value>::type Invoke(Args&&... args, T&& aspect)
{
m_func(forward<Args>(args)...); //核心逻辑
aspect.After(forward<Args>(args)...); //核心逻辑之后的切面逻辑
}
template<typename Head,typename...Tail>
void Invoke(Args&&... args,Head&&headAspect,Tail&&...tailAspect)
{
headAspect.Before(forward<Args>(args)...);
Invoke(forward<Args>(args)..., forward<Tail>(tailAspect)...);
headAspect.After(forward<Args>(args)...);
}
private:
Func m_func;
};
template<typename T> using identity_t = T;
// AOP的辅助函数,简化调用
template<typename... AP,typename... Args,typename Func>
void Invoke(Func&& f, Args&&... args)
{
Aspect<Func, Args...>asp(forward<Func>(f));
asp.Invoke(forward<Args>(args)..., identity_t<AP>()...);
}
带日志切面的AOP测试:
// AOP.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include "pch.h"
#include <iostream>
#include "AOP.h"
#include <functional>
#include <chrono>
using namespace std;
using namespace std::chrono;
class Timer
{
public:
Timer() :m_begin(high_resolution_clock::now()) {}
void reset() { m_begin = high_resolution_clock::now(); }
// 默认输出毫秒
template<typename Duration = microseconds>
int64_t elapsed() const
{
return duration_cast<Duration>(high_resolution_clock::now() - m_begin).count();
}
// 微秒
int64_t elapsed_micro() const
{
return elapsed<microseconds>();
}
// 纳秒
int64_t elapsed_nano()const
{
return elapsed<nanoseconds>();
}
// 秒
int64_t elapsed_seconds()const
{
return elapsed<seconds>();
}
int64_t elapsed_minutes()const
{
return elapsed<minutes>();
}
int64_t elasped_hours()const
{
return elapsed<hours>();
}
private:
time_point<high_resolution_clock> m_begin;
};
struct AA
{
void Before(int i)
{
cout << "Before from AA " << i << endl;
}
void After(int i)
{
cout << "After from AA " << i << endl;
}
};
struct BB
{
void Before(int i)
{
cout << "Before from BB " << i << endl;
}
void After(int i)
{
cout << "After from BB " << i << endl;
}
};
struct CC
{
void Before()
{
cout << "Before from CC " << endl;
}
void After()
{
cout << "After from CC " << endl;
}
};
struct DD
{
void Before()
{
cout << "Before from DD "<< endl;
}
void After()
{
cout << "After from DD " << endl;
}
};
void GT()
{
cout << "real GT function" << endl;
}
void HT(int a)
{
cout << "real HT function: " << a<<endl;
}
struct TimeElapsedAspect
{
void Before(int i)
{
}
void After(int i)
{
cout << "time elapsed: " << m_t.elapsed()-m_lastTime<<endl;
}
private:
double m_lastTime;
Timer m_t;
};
struct LoggingAspect
{
void Before(int i)
{
cout << "entering" << endl;
}
void After(int i)
{
cout << "leaving" << endl;
}
};
void foo(int a)
{
cout << "real HT function: " << a << endl;
}
int main()
{
//织入普通函数
function<void(int)> f = bind(&HT, placeholders::_1);
Invoke<AA, BB>(function<void(int)>(bind(&HT,placeholders::_1)),1);
// 组合了两个切面AA,BB
Invoke<AA, BB>(f, 1);
// 织入普通函数
Invoke<CC, DD>(>);
Invoke<AA, BB>(&HT, 1);
// 织入lambda表达式
Invoke<AA, BB>([](int i) {},1);
Invoke<CC, DD>([] {});
{
cout << "--------------------" << endl;
Invoke<LoggingAspect,TimeElapsedAspect>(&foo, 1);
cout << "----------------------" << endl;
Invoke<TimeElapsedAspect, LoggingAspect>(&foo, 1);
cout << "--------------------" << endl;
}
}
结果显示: