std::tr1::bind 或 std::tr1::function使用

来源:互联网 发布:对网络教育的看法作文 编辑:程序博客网 时间:2024/06/08 06:35
参考博客网址:http://blog.csdn.net/kiang3/article/details/7571647


一、常规OO设计:
写一个Thread base class,含有(纯)虚函数 Thread#run(),然后应用程序派生一个继承class,覆写run()。程序里的每一种线程对应一个Thread的派生类。例如Java的Thread可以这么用。
缺点:如果一个class的三个method需要在三个不同的线程中执行,就得写helper class(es)并玩一些OO把戏。


基于closure的设计:
令Thread是一个具体类,其构造函数接受Callable对象。应用程序只需提供一个Callable对象,创建一份Thread实体,调用Thread#start()即可。Java的Thread也可以这么用,传入一个Runnable对象。C#的Thread只支持这一种用法,构造函数的参数是delegate ThreadStart。boost::thread也只支持这种用法。

// 一个基于 closure 的 Thread class 基本结构
class Thread 

public: 
typedef boost::function<void()> ThreadCallback; 
Thread(ThreadCallback cb) : cb_(cb) 
{ } 
void start() 

/* some magic to call run() in new created thread */ 

private: 
void run() 

cb_(); 

ThreadCallback cb_; 
// ... 
}; 


使用:
class Foo
{
public:
void runInThread();
};


Foo foo;
Thread thread(boost::bind(&Foo::runInThread, &foo));
thread.start();

二、基于接口的设计
这个问题来自那个经典的讨论:不会飞的企鹅(Penguin)究竟应不应该继承自鸟(Bird),如果Bird定义了virtual function fly()的话。讨论的结果是,把具体的行为提出来,作为interface,比如Flyable(能飞的),Runnable(能跑的),然后让企鹅实现Runnable,麻雀实现Flyable和Runnable。(其实麻雀只能双脚跳,不能跑,这里不作深究。)进一步的讨论表明,interface的粒度应足够小,或许包含一个method就够了,那么interface实际上退化成了给类型打的标签(tag)。
在这种情况下,完全可以使用boost::function来代替,比如:


// 企鹅能游泳,也能跑
class Penguin
{
public:
void run();
void swim();
};


// 麻雀能飞,也能跑
class Sparrow
{
public:
void fly();
void run();
};


// 以 closure 作为接口
typedef boost::function<void()> FlyCallback;
typedef boost::function<void()> RunCallback;
typedef boost::function<void()> SwimCallback;


// 一个既用到run,也用到fly的客户class
class Foo
{
public:
Foo(FlyCallback flyCb, RunCallback runCb) : flyCb_(flyCb), runCb_(runCb)
{ }
private:
FlyCallback flyCb_;
RunCallback runCb_;
};

// 一个既用到run,也用到swim的客户class
class Bar
{
public:
Bar(SwimCallback swimCb, RunCallback runCb) : swimCb_(swimCb), runCb_(runCb)
{ }
private:
SwimCallback swimCb_;
RunCallback runCb_;
};


int main()
{
Sparrow s;
Penguin p;
// 装配起来,Foo要麻雀,Bar要企鹅。
Foo foo(bind(&Sparrow::fly, &s), bind(&Sparrow::run, &s));
Bar bar(bind(&Penguin::swim, &p), bind(&Penguin::run, &p));
}
原创粉丝点击