面向切面编程--AOP

转自:https://www.cnblogs.com/qicosmos/archive/2013/04/07/3003480.html


(原创) C++ 轻量级AOP框架

c++11 boost技术交流群:296561497,欢迎大家来交流技术。

c++中开源的AOP框架AspectC++需要单独编译才能将切面的代码织入到核心逻辑代码中,感觉使用起来不方便,不能满足快速开发要求。我希望只要实现方法拦截即可,能织入before()和after()操作就行,不追求动态织入。思路是这样的,通过一个包装类,里面定义before()和after()方法,和->运算符重载方法,在重载操作函数中实现before()和after()操作。具体代码如下:

复制代码
 1 #include <boost/shared_ptr.hpp>
 2 
 3 template <typename WrappedType, typename DerivedAspect>
 4 class BaseAspect
 5 {
 6 protected:
 7   WrappedType* m_wrappedPtr; //被织入的对象
 8 
 9   //获取派生的切面对象
10   DerivedAspect* GetDerived() 
11   {
12     return static_cast<DerivedAspect*>(this);
13   }
14 
15   //被织入对象的删除器,用来自动触发切面中的After方法
16   struct AfterWrapper
17   {
18     DerivedAspect* m_derived;
19     AfterWrapper(DerivedAspect* derived): m_derived(derived) {};
20     void operator()(WrappedType* p)
21     {
22       m_derived->After(p);
23     }
24   };
25 public:
26   explicit BaseAspect(WrappedType* p) :  m_wrappedPtr(p) {};
27 
28 
29   void Before(WrappedType* p) {
30      // Default does nothing
31   };
32 
33   void After(WrappedType* p) {
34      // Default does nothing
35   }
36 
37   //重载指针运算符用来织入切面(Before和After)
38   boost::shared_ptr<WrappedType> operator->() 
39   {
40     GetDerived()->Before(m_wrappedPtr);
41     return boost::shared_ptr<WrappedType>(m_wrappedPtr, AfterWrapper(GetDerived()));
42   }
43 };
44 
45 //织入切面的工厂函数, 返回包含被织入对象的切面
46 template <template <typename> class Aspect, typename WrappedType> 
47 Aspect<WrappedType> MakeAspect(WrappedType* p) 
48 {
49   return Aspect<WrappedType>(p);
50 }
复制代码

BaseAspect为切面的基类,提供了Before()和After()方法,供派生的切面实现;

 

下面看看具体的切面实现:一个实现对函数运行时间的统计,一个实现日志功能。

复制代码
 1 #include <iostream>
 2 #include <boost/chrono/chrono.hpp>
 3 #include <boost/chrono/system_clocks.hpp>
 4 
 5 template<typename WrappedType>
 6 class TimeElapsedAspect : public BaseAspect< WrappedType, TimeElapsedAspect<WrappedType> >
 7 {
 8   typedef  BaseAspect<WrappedType, TimeElapsedAspect<WrappedType> > BaseAspect;
 9   typedef boost::chrono::time_point<boost::chrono::system_clock, boost::chrono::duration<double> > time_point;
10 
11   time_point m_tmBegin;
12 public:
13   TimeElapsedAspect(WrappedType* p): BaseAspect(p) {}
14 
15 
16   void Before(WrappedType* p) 
17   {
18     m_tmBegin = boost::chrono::system_clock::now();
19   }
20 
21   void After(WrappedType* p)
22   {
23     time_point end = boost::chrono::system_clock::now();
24 
25     std::cout << "Time: " << (end-m_tmBegin).count() << std::endl;
26   }
27 };
复制代码

TimeElapsedAspect切面实现对函数运行时间统计。

 

复制代码
 1 template <typename WrappedType>
 2 class LoggingAspect : public BaseAspect<WrappedType, LoggingAspect<WrappedType> >
 3 {
 4   typedef  BaseAspect<WrappedType, LoggingAspect<WrappedType> > BaseAspect;
 5 public:
 6   LoggingAspect(WrappedType* p): BaseAspect(p) {}
 7 
 8   void Before(WrappedType* p) 
 9   {
10     std::cout << "entering" << std::endl;
11   }
12 
13   void After(WrappedType* p) 
14   {
15     std::cout << "exiting" << std::endl;
16   }
17 
18 };
复制代码

LoggingAspect实现日志记录

 

现在来看看测试代码

复制代码
class IX
{
public:IX(){}virtual ~IX(){}virtual void g()=0;
private:};class X : public IX
{
public:void g() {std::cout << "it is a test" << std::endl;}};void TestAop()
{boost::shared_ptr<IX> p(new X());MakeAspect<TimeElapsedAspect>(p.get())->g();MakeAspect<LoggingAspect>(p.get())->g();
}
复制代码

 测试结果:

总结:

这个简单的AOP实现,可以实现对类的方法进行拦截,具体切面自由定制,不过还有个地方不太完善,还不支持切面的组合,这个可以用TypeList去实现。

一点梦想:尽自己一份力,让c++的世界变得更美好!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/509255.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

面向切面编程--AOP(二)

转自&#xff1a;http://www.cnblogs.com/qicosmos/p/3154174.html (原创)c11改进我们的模式之改进代理模式&#xff0c;实现通用的AOP框架 c11 boost技术交流群&#xff1a;296561497&#xff0c;欢迎大家来交流技术。 本次要讲的时候如何改进代理模式&#xff0c;具体来说是动…

VS2013+VSVIM

上世纪90年代后期出现了一股.com热潮&#xff0c;相信大家对其都有美好的回忆&#xff0c;那时使用CGI和Perl创建“动态的”网站&#xff0c;通过使用在Unix上的vi编辑器快速打字和格式化&#xff0c;这也包括后来使用的vi的复制版本vim。我可能是怀旧的&#xff0c;但我想念将…

一个程序员的日常书单

本想谈谈读书这个话题,想来想起觉得无从下手,就此作罢.毕业这几年,一直不敢放松,在现代这个互联网时代更加认同萧抡谓的”一日不读书,胸臆无佳想;一月不读书,耳目失清爽”.如果非要给自己找个读书的理由的话,这句诗就是最好的理由:”胸藏文墨虚若骨,腹有诗书气自华”. 与书结缘…

Amr and Pins

Description Amr loves Geometry. One day he came up with a very interesting problem. Amr has a circle of radius r and center in point (x, y). He wants the circle center to be in new position (x, y). In one step Amr can put a pin to the border of the circl…

分布式系统的工程化开发方法

转自&#xff1a;http://blog.csdn.net/solstice/article/details/5950190 以下是我在珠三角技术沙龙 2010Q4 上的演讲投影片。 演讲视频&#xff1a; http://www.youku.com/playlist_show/id_5238686.html ---------- ---------- ------

程序员的知识广度

转自&#xff1a;http://blog.csdn.net/EGEFCXzo3Ha1x4/article/details/79070190 “知识变现”的口号一喊 确实让很多人都摩拳擦掌蓄势待发 那么作为程序员的mu们 不管是思维逻辑&#xff0c;还是知识广度 是不是都迫不及待了 今天&#xff0c;我们也来测试下 【单选题】 1 …

多线程---条件变量

互斥器和条件变量的区别&#xff1a;互斥器具有加锁原语&#xff0c;用来进行排他性的访问共享数据&#xff0c;而条件变量具有等待原语&#xff0c;用于等待某个事件的发生。 等待条件变量的正确姿势&#xff1a; void wait() {mutex.lock()while (wait_flag false) {conditi…

ARP-地址解析协议(在实践中深入理解ARP协议)

在同一个网络&#xff08;无特别说明&#xff0c;均指以太网络&#xff09;中进行通信的主机&#xff0c;必须要拥有目标主机的MAC地址才能够正确地将数据发送给目标主机&#xff0c;那么如何知道目标主机的MAC地址呢&#xff1f;可以通过ARP协议。ARP协议就是用来获取目标IP地…

Maven私服

1 Maven私服简介 Maven 私服是一种特殊的Maven远程仓库&#xff0c;它是架设在局域网内的仓库服务&#xff0c;用来代理位于外部的远程仓库&#xff08;中央仓库、其他远程公共仓库&#xff09;。 1.1 下载构件顺序 建立私服后&#xff0c;当局域网内的用户需要某个构件时&a…

Unity3d--跨平台(一)

转自&#xff1a;https://www.cnblogs.com/murongxiaopifu/p/4211964.html前言&#xff1a; 其实小匹夫在U3D的开发中一直对U3D的跨平台能力很好奇。到底是什么原理使得U3D可以跨平台呢&#xff1f;后来发现了Mono的作用&#xff0c;并进一步了解到了CIL的存在。所以&#xff0…

linux定时任务的用法详解

crontab的基本格式&#xff1a; f1  f2  f3  f4  f5  command 分  时 日  月  周  命令 第一列f1代表分钟1~59&#xff1a;当f1为表示每分钟都要执行&#xff1b;为/n表示每n分钟执行一次&#xff1b;为a-b表示从第a分钟到第b分钟这段时间要执行&#xff1b;为a,…

Unity3d-跨平台(二)

转自&#xff1a;http://www.jiandaima.com/blog/archives/945.html 是如何输出到多平台的&#xff1f; 我的第一篇文章&#xff0c;选择了一个不那么简单的主题&#xff0c;但是是我近期比较感兴趣的。这周&#xff0c;我和一个朋友&#xff0c;谈到了游戏开发和Unity3D&#…

svn冲突解决方案

解决方法 步骤一、清空svn的队列 1、进入到项目的.svn目录中&#xff0c;查看是否存在wc.db文件 C:\Users\Administrator>D:D:\>cd D:\BBK_SVN\I3_TrunkD:\BBK_SVN\I3_Trunk>cd .svnD:\BBK_SVN\I3_Trunk\.svn>dirVolume in drive D has no label.Volume Serial Nu…

redis集群搭建与配置

redis集群搭建与配置

keepalived的安装与添加服务

keepalived的安装与添加服务

Mr. Bender and Square

Description Mr. Bender has a digital table of size n  n, each cell can be switched on or off. He wants the field to have at least c switched on squares. When this condition is fulfilled, Mr Bender will be happy. Well consider the table rows numbered from…

keepalived+nginx保持高可用配置

安装nginx、keepalived nginx安装 keepalived安装与添加服务在/etc/keepalived目录下新建nginx_check.sh&#xff08;两台服务器都需要&#xff09; 配置keepalived.conf: #配置邮箱 global_defs {notification_email {# acassenfirewall.loc# failoverfirewall.loc# sysadmin…

nginx+keepalived详细配置信息

Nginx Keepalived 第一步&#xff1a; 下载keepalived地址&#xff1a;http://www.keepalived.org/download.html 解压安装&#xff1a; tar -zxvf keepalived-1.2.18.tar.gz -C /usr/local/ yum install -y openssl openssl-devel&#xff08;需要安装一个软件包&#xff09…

毕业3年,为何技术能力相差越来越大?

导读&#xff1a;毕业三年&#xff0c;每个人在技术能力跑道上&#xff0c;有了或大或小的差距。有些人永远在重复的劳动&#xff0c;有些人却能从中总结和解决问题。今天我们来探讨下&#xff0c;如何避免让战术上的勤奋掩盖战略上的懒惰&#xff0c;使得真正掌握好的知识点慢…

Periodic Signal

描述 Profess X is an expert in signal processing. He has a device which can send a particular 1 second signal repeatedly. The signal is A0 ... An-1 under n Hz sampling. One day, the device fell on the ground accidentally. Profess X wanted to check whether …