青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

qiezi的學習園地

AS/C/C++/D/Java/JS/Python/Ruby

  C++博客 :: 首頁 :: 新隨筆 ::  ::  :: 管理 ::
Aspect C++支持“虛切面”,類似C++中的虛函數。方面可以繼承,“派生方面”可以重寫“基方面”的“虛切面”,類似C++中的類繼承。

有了這個特性,就可以實現一些模式了,這里列出AOP中經典的觀察者(Observer)模式[注]

[注]這個說法不太妥當,觀察者模式是經典的設計模式,這里的意思是說AOP經典的觀察者模式實現。

它的代碼如下:

aspect ObserverPattern {
    
// 管理subjects和observers的數據結構
    
// TODO 
public:
    
// 角色接口
    struct ISubject {};
    
struct IObserver {
        
virtual void update(ISubject *= 0;
    };
    
// 在派生方面中被重寫
    pointcut virtual observers () = 0;
    pointcut 
virtual subjects () = 0;
    
// subjectChange()匹配所有非const方法,但限定了subjects類
    pointcut virtual subjectChange () =
        execution(
" % ::%(" && !" % ::%() const")
        
&& within(subjects ());
    
// 為每個subject/observer類增加基類,并插入通知代碼
    advice observers () : baseclass(IObserver );
    advice subjects () : baseclass(ISubject );
    advice subjectChange () : after() {
        ISubject 
* subject = tjp->that ();
        updateObservers (subject );
    }
    
// 具體操作
    void updateObservers (ISubject * sub ) {  }
    
void addObserver (ISubject * sub , IObserver * ob ) {  }
    
void remObserver (ISubject * sub , IObserver * ob ) {  }
};

其中“...” 部分是需要完成的C++實現代碼,可以簡單實現一個:
#ifndef __OBSERVER_PATTERN_AH__
#define __OBSERVER_PATTERN_AH__

#include 
<map>
#include 
<set>
using namespace std;

aspect ObserverPattern {
    
// 管理subjects和observers的數據結構
    struct ISubject;
    
struct IObserver;
    map 
< ISubject*set<IObserver*> > listeners;
public:
    
// 角色接口
    struct ISubject {};
    
struct IObserver {
        
virtual void update(ISubject *= 0;
    };
    
// 在派生方面中被重寫
    pointcut virtual observers () = 0;
    pointcut 
virtual subjects () = 0;
    
// subjectChange()匹配所有非const方法
    pointcut virtual subjectChange () =
        execution(
" % ::%(" && !" % ::%() const")
        
&& within(subjects ());
    
// 為每個subject/observer類增加基類,并插入通知代碼
    advice observers () : baseclass(IObserver );
    advice subjects () : baseclass(ISubject );
    advice subjectChange () : after() {
        ISubject 
* subject = tjp->that ();
        updateObservers (subject );
    }
    
// 具體操作
    void updateObservers (ISubject * sub ) {
        
const set<IObserver*>& observers = listeners[sub];
        
set<IObserver*>::const_iterator iter = observers.begin();
        
for (; iter != observers.end(); iter ++)
        {
            (
*iter)->update(sub);
        }
    }
    
void addObserver (ISubject * sub , IObserver * ob ) { listeners[sub].insert(ob); }
    
void removeObserver (ISubject * sub , IObserver * ob ) { listeners[sub].erase(ob); }
};

#endif // __OBSERVER_PATTERN_AH__

保存為ObserverPattern.ah供下面使用。

下面編寫一個應用實例:

1、car.h

#ifndef __CAR_H__
#define __CAR_H__

#include 
<string>
using namespace std;

class Car
{
    
string name;
    
int x;
    
int y;
    
enum Direction{South, East, North, West};
    Direction direction;

    Car (
const Car&);
    Car
& operator = (const Car&);
public:
    Car (
const string& name);
    
void turnLeft ();
    
void turnRight ();
    
void forward (size_t step);

    
const string& getName() const;
    
int getX () const;
    
int getY () const;
    Direction getDirection () 
const;
};



#endif // __CAR_H__


2、car.cc

#include 
"car.h"
#include 
<cassert>

Car::Car (
const string& name_)
: name(name_), x(
0), y(0), direction(South)
{
}

void Car::turnLeft ()
{
    
if (direction == West)
        direction 
= South;
    
else
        direction 
= (Direction)(int(direction) + 1);
}

void Car::turnRight ()
{
    
if (direction == South)
        direction 
= West;
    
else
        direction 
= (Direction)(int(direction) - 1);
}

void Car::forward (size_t step)
{
    
switch (direction)
    {
    
case South:
        y 
+= step; break;
    
case East:
        x 
+= step; break;
    
case North:
        y 
-= step; break;
    
case West:
        x 
-= step; break;
    
default:
        assert (
!"Invalid direction");
    }
}

const string& Car::getName() const
{
    
return name;
}

int Car::getX() const
{
    
return x;
}

int Car::getY() const
{
    
return y;
}

Car::Direction Car::getDirection() 
const
{
    
return direction;
}

3、dummy.h(這個用來測試Aspect C++的匹配模式會不會混亂)
#ifndef __DUMMY_H__
#define __DUMMY_H__

class Dummy
{
public:
    
void test_non_const (){}
    
void test_const () const {}
};

#endif // __DUMMY_H__

4、main.cc
#include "car.h"
#include 
"dummy.h"

int main()
{
    Car car(
"No.1");
    car.turnLeft();
    car.forward(
3);
    car.turnLeft();
    car.forward(
9);
    car.turnRight();
    car.forward(
12);

    Car car1(
"No.2");
    car1.forward(
7);
    car1.turnLeft();
    car1.forward(
3);

    car.forward(
5);

    Dummy dummy;
    dummy.test_non_const();
    dummy.test_const();
    
    
return 0;
}

這個程序編譯運行,沒有任何輸出。有時候為了監視對象的狀態,可以在執行一個操作后加上一些打印狀態的代碼,當然這樣比較繁瑣;也可以在各個操作函數中加入這些代碼,但修改已經寫好的代碼總是不太舒服。

下面先實現一個Car狀態打印類:

5、car_logging.h
#ifndef __CAR_LOGGING__
#define __CAR_LOGGING__

#include 
"car.h"
#include 
<iostream>
using namespace std;

class CarLogging
{
public:
    
void printCarInfo (const Car& car)
    {
        
static const char* direction_str[] = {"South""East""North""West"};
        cout 
<< "Car name: " << car.getName()
            
<< ", direction: " << direction_str[int(car.getDirection())] 
            
<< ", x: " << car.getX() 
            
<< ", y: " << car.getY() 
            
<< endl;
    }
};

extern CarLogging g_carLogging;

#endif // __CAR_LOGGING__

6、car_logging.cc
#include "car_logging.h"

CarLogging g_carLogging;

7、CarLoggingObserver.ah
#ifndef __CAR_LOGGING_OBSERVER_AH__
#define __CAR_LOGGING_OBSERVER_AH__

#include 
"ObserverPattern.ah"
#include 
"car.h"
#include 
"car_logging.h"

aspect CarLoggingObserver : 
public ObserverPattern {
    
// 定義方面(ointcuts)
    pointcut subjects() = "Car";
    pointcut observers() 
= "CarLogging";
public:
    advice observers() :
    
void update( ObserverPattern::ISubject* sub ) {
        printCarInfo (
*(Car*)sub);
    }

    advice construction (classes(subjects())) : after()
    {
        addObserver(tjp
->that(), &g_carLogging);
    }

    advice destruction (classes(subjects())) : before()
    {
        removeObserver(tjp
->that(), &g_carLogging);
    }
};

#endif // __CAR_LOGGING_OBSERVER_AH__

這個方面重寫了subjects以及observers切面,并定義了observers在update被調用時執行的操作,另外還在Car的構造函數和析構函數中添加了注冊和注銷代碼。

運行ac++生成代碼,編譯并運行,結果如下:

這里演示的例子依舊選擇了不影響原始程序的做法,網上很多資料都把這個模式和實現代碼結合起來,由于Aspect C++編譯速度還是很慢,所以選擇“外掛”的方式,這樣不需要這些方面時,直接編譯C++代碼即可。

關于Aspect C++以及AOP,還有許多話題,不過不打算再繼續了,AOP是個廣泛的議題,局限在某一實現上只會使我們眼界變窄。

AOP被稱為設計模式最佳實踐者,它當之無愧。網上還有很多AOP實踐設計模式的資料。
posted on 2005-12-17 10:21 qiezi 閱讀(1723) 評論(0)  編輯 收藏 引用 所屬分類: C++
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美第一黄色网| 午夜精品在线观看| 国产精品久线观看视频| 国产日韩亚洲欧美| 国产欧美日韩精品丝袜高跟鞋| 国产亚洲一区二区三区在线观看| 亚洲理论在线观看| 亚洲精品韩国| 日韩系列欧美系列| 亚洲欧美精品中文字幕在线| 欧美成人激情视频免费观看| 欧美黄色免费网站| 午夜精品成人在线| 亚洲一区二区三区精品在线| 亚洲国产1区| 一本色道久久综合| 免费观看30秒视频久久| 久久国产视频网站| 亚洲精品乱码久久久久久黑人| 一区二区三区高清在线| 亚洲人成7777| 欧美日本韩国在线| 性感少妇一区| 亚洲欧美另类在线观看| 免费欧美日韩| 一区二区三区www| 亚洲一区在线免费观看| 欧美视频中文字幕在线| 欧美不卡高清| 亚洲国产高潮在线观看| 久久精品国产精品亚洲| 亚洲美女黄色片| 亚洲男人第一av网站| 国产亚洲一级高清| 欧美一区成人| 99精品视频免费| 激情小说亚洲一区| 鲁大师成人一区二区三区| 亚洲国产成人精品女人久久久| 在线观看日韩av| 99这里只有精品| 欧美成人高清| 亚洲国产一区在线观看| 亚洲一区二区视频在线| 欧美诱惑福利视频| 国产精品午夜国产小视频| 欧美韩国在线| 亚洲欧洲偷拍精品| 日韩亚洲国产精品| 亚洲高清不卡在线| 国产视频精品va久久久久久| 欧美成人免费大片| 亚洲欧美制服中文字幕| 久久综合网hezyo| 一区二区三区国产精品| 亚洲第一黄网| 麻豆乱码国产一区二区三区| 亚洲伦理在线观看| 欧美大尺度在线| 亚洲午夜视频在线| 亚洲高清资源| 久久久久久久高潮| 亚洲一品av免费观看| 最新69国产成人精品视频免费| 国产精品久久久久久久久久免费 | 国产欧美va欧美不卡在线| 久久综合久久美利坚合众国| 亚洲一区二区三| 亚洲人成网站色ww在线| 久热国产精品视频| 久久成年人视频| 亚洲一区精品视频| 在线播放豆国产99亚洲| 国产日产亚洲精品| 欧美日韩一区二区免费在线观看 | 亚洲一区二区黄色| 日韩一级黄色片| 亚洲第一网站| 亚洲电影免费观看高清完整版在线 | 亚洲精品国产系列| 久久视频在线视频| 中文精品视频| 最新国产精品拍自在线播放| 136国产福利精品导航网址应用| 亚洲国产另类精品专区| 性高湖久久久久久久久| 一本大道av伊人久久综合| 亚洲国产精品va| 欧美激情综合色| 欧美韩日亚洲| 欧美黄色影院| 欧美成ee人免费视频| 免费欧美在线| 欧美高清视频在线播放| 欧美高清在线精品一区| 欧美黄色免费| 这里只有精品丝袜| 亚洲精品乱码久久久久久黑人| 亚洲黄色有码视频| 在线视频欧美一区| 亚洲一区二区动漫| 久久成人国产精品| 老巨人导航500精品| 麻豆9191精品国产| 欧美日韩国内| 国产精品男gay被猛男狂揉视频| 亚洲欧美日韩电影| 欧美一区=区| 麻豆精品在线播放| 欧美精品日日鲁夜夜添| 国产精品大片wwwwww| 国产精品一区二区女厕厕| 国内精品国产成人| 亚洲国产精品久久久久秋霞不卡 | 亚洲国产黄色| 亚洲激情视频网站| 亚洲一区二区欧美| 午夜精品www| 免费观看在线综合| 亚洲最快最全在线视频| 亚洲淫性视频| 麻豆九一精品爱看视频在线观看免费| 欧美激情精品久久久六区热门| 国产精品福利在线观看网址| 国产精品一二三四| 在线观看亚洲视频| 中文精品在线| 欧美一区二区三区免费视| 欧美福利专区| 亚洲一区观看| 欧美大色视频| 国产精品一区二区久久精品| 国产综合网站| 亚洲欧美在线视频观看| 欧美成人福利视频| 亚洲午夜精品久久久久久app| 久久精品在这里| 欧美少妇一区| 亚洲福利视频三区| 欧美一区1区三区3区公司| 免费成人性网站| 亚洲小说欧美另类婷婷| 久久久国产精品一区二区三区| 欧美日韩成人综合天天影院| 黄色成人精品网站| 一本大道av伊人久久综合| 久久一区国产| 欧美激情视频一区二区三区免费 | 国产亚洲欧美在线| 欧美在线一二三区| 久久―日本道色综合久久| 奶水喷射视频一区| 欧美日韩一区二区三区视频| 欧美激情亚洲| 久久婷婷av| 久久精品亚洲精品国产欧美kt∨| a4yy欧美一区二区三区| 久久成人一区二区| 亚洲一区二区动漫| 欧美国产另类| 欧美在线观看你懂的| 欧美婷婷久久| 亚洲免费观看高清在线观看| 美日韩免费视频| 亚洲欧美国产日韩中文字幕| 国产精品黄页免费高清在线观看| 亚洲精品欧美| 欧美超级免费视 在线| 欧美一级视频免费在线观看| 国产精品久久久久久久久免费| 一区二区三区久久精品| 亚洲激情视频在线| 亚洲成色最大综合在线| 欧美肉体xxxx裸体137大胆| 国产一区二区三区电影在线观看| 亚洲午夜高清视频| 久久综合久久综合久久综合| 午夜精品久久久久久久久久久久久 | 亚洲色图在线视频| 日韩亚洲欧美在线观看| 欧美精品videossex性护士| 亚洲精品日韩一| 亚洲国产成人精品久久久国产成人一区 | 一本久久综合亚洲鲁鲁五月天| 欧美二区视频| 日韩西西人体444www| 亚洲黄色精品| 欧美另类亚洲| 亚洲一区二区在线看| 在线午夜精品| 国产精品久久网站| 性色av一区二区三区在线观看| 亚洲一区二区三区成人在线视频精品| 国产精品久久久久久超碰 | 中文精品在线| 宅男精品视频| 国产一区99| 欧美大片一区二区三区| 美女爽到呻吟久久久久| 99爱精品视频|