面向切面编程--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,一经查实,立即删除!

相关文章

IQ超过250

Problem Description 李华是一个十分聪明的同学&#xff0c;据说他的智商高达250多&#xff0c;但是今天他竟然被一道题给卡住了&#xff0c;是什么题呢&#xff1f;题目内容为&#xff1a; 给你n个数&#xff0c;然后让你判断能否用这n个数中的一些数,使他们的和组成所有的非负…

9个基于Java的搜索引擎框架

9个基于Java的搜索引擎框架 转自&#xff1a;http://blog.csdn.net/xiaomin1991222/article/details/50980573 1、Java 全文搜索引擎框架 Lucene 毫无疑问&#xff0c;Lucene是目前最受欢迎的Java全文搜索框架&#xff0c;准确地说&#xff0c;它是一个全文检索引擎的架构&a…

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

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

TimesIsMoney

Problem Description 给你一个序列&#xff0c;有N个整数&#xff08;int以内&#xff09;&#xff0c;判断一个数在这个序列中出现几次。 Input 多组输入&#xff0c;输入到文件结尾 首先输入一个n&#xff0c;然后输入n个整数。 在输入一个m&#xff0c;代表查询的个数 &…

redis参考优秀文章

文章地址 写的很详细&#xff0c;做个记录

VS2013常用快捷键设置

Visual Studio 2013 是一个基本完整的开发工具集&#xff0c;它包括了整个软件生命周期中所需要的大部分工具&#xff0c;如UML工具、代码管控工具、集成开发环境(IDE)等等。VS 2013 中新增了很多提高开发人员工作效率的新功能&#xff0c;比如自动补全方括号、使用快捷键移动整…

多次访问redis造成redis连接总是断开的解决方案

之前做了一个新闻推荐项目用到redis&#xff0c;当把项目发布到线上去测试的时候&#xff0c;用两个redis(线上服务采用LVS负载均衡&#xff0c;两个可以切换)的时候发现开始跑的时候没有问题&#xff0c;但是过一段时间当用户访问量特别大的时候有一个redis总断开连接的问题&a…

USB Flash Drives

Description Sean is trying to save a large file to a USB flash drive. He has n USB flash drives with capacities equal to a1, a2, ..., an megabytes. The file size is equal to m megabytes. Find the minimum number of USB flash drives needed to write Seans …

VS2013+VSVIM

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

activeMQ发送与接受消息模板代码

发送着&#xff1a; /*** */ package activemqAPI.helloworld;import javax.jms.Connection; import javax.jms.ConnectionFactory; import javax.jms.DeliveryMode; import javax.jms.Destination; import javax.jms.JMSException; import javax.jms.MessageProducer; import …

做一个优秀的项目/产品经理

1、工作中&#xff0c;在时间、质量、成本三者之间找到平衡&#xff0c;带领团队成功研发并上线项目。 解决好以下细节问题&#xff0c;就达到一个合格IT项目经理了&#xff1a; 项目的由来&#xff0c;为什么要建立这么一个系统&#xff1f; 项目有计划吗&#xff1f; 项目的需…

一个程序员的日常书单

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

【转载】ssdb安装部署

转载地址&#xff1a;https://www.cnblogs.com/dyfblog/p/5894518.html ssdb是一款类似于redis的nosql数据库&#xff0c;不过redis是基于内存的&#xff0c;服务器比较昂贵&#xff0c;ssdb则是基于硬盘存储的&#xff0c;很容易扩展&#xff0c;对于一些对速度要求不是太高的…

2017年回顾及总结

从2015毕业至今&#xff0c;在c开发领域算起来已经差不多两年多的时间了。在这三年的时间里&#xff0c;涉及到的c领域的技术基本上从广度上有了一个大概的学习和认知。各个方面的知识都有所掌握&#xff0c;包括c底层实现&#xff0c;网络通信&#xff0c;并行开发&#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…

TCP/IP学习

http://blog.csdn.net/column/details/15153.html?

ngnix 作用(通俗易懂)【转载】

作者&#xff1a;RayeWang www.raye.wang/2017/02/24/quan-mian-liao-jie-nginxdao-di-neng-zuo-shi-yao/ 前言 本文只针对Nginx在不加载第三方模块的情况能处理哪些事情&#xff0c;由于第三方模块太多所以也介绍不完&#xff0c;当然本文本身也可能介绍的不完整&#xff0…

C++11并发实战(专栏)

http://blog.csdn.net/column/details/ccia.html?&page2

LCIS

Problem DescriptionAlex has two sequences a_1,a_2,...,a_na​1​​,a​2​​,...,a​n​​ and b_1,b_2,...,b_mb​1​​,b​2​​,...,b​m​​. He wants find a longest common subsequence that consists of consecutive values in increasing order. InputThere are mu…

TimeUnit.SECONDS.sleep()和sleep区别

刚看到TimeUnit.SECONDS.sleep()方法时觉得挺奇怪的&#xff0c;这里怎么也提供sleep方法&#xff1f; public void sleep(long timeout) throws InterruptedException {if (timeout > 0) {long ms toMillis(timeout);int ns excessNanos(timeout, ms);Thread.sleep(ms, …