您的位置:首页 > 其它

类的成员函数作为回调函数的方法

2013-11-12 13:24 381 查看
“类中的成员” 函数不能作为本身的回调,如果非要这样弄可以有几个办法,

例如静态方式声明,提供this指针等,

针对static的话我想失去了回调在类中使用的意义,

网上可以搜索下提供this指针方式,之前搜索时候看到过

另外就是间接将类中成员变成回调,其过程就是利用间接的一个方法调用这个回调,然后设置回调函数的地方使用这个中间的方法(在此谢过给过帮助的同学)

如下我以使用zookeeper来说明(其中需要声明回调用于监测//)

/*

author: programer.moo@gamil.com

name: zk_frameword.h

*/

#ifndef _ZK_FRAMEWORK_H

#define _ZK_FRAMEWORK_H

#include <iostream>

#include <stdlib.h>

#include <tr1/functional>

#include "zookeeper/zookeeper.h"

namespace detail { class ZooKeeperWatcher; }

class ZKOP{

public:

ZKOP();

~ZKOP();

public:

typedef std::tr1::function<void(const char* path, int type, int state)> wrapFunc;

typedef String_vector zkVector;

public:

bool zkInit(const std::string& host, const wrapFunc& func, const int timeout);

void zkWatcher(const char* path, int type, int state);

/*others*/

private:

zhandle_t* zkhandle;

detail::ZooKeeperWatcher* context_;

clientid_t clientid_;

};

#endif//endif zk_frame.h

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/*

name=zk_frame.cpp

author=programer.moo@gmail.com

*/

/**

* we must wrap a class to call member function in ZKOP

* because member function cannot be callback function

*/

namespace detail

{//这个就是包的中间层

class ZooKeeperWatcher

{/*{{{*/

public:

typedef ZKOP::wrapFunc wrapFunc;

public:

explicit ZooKeeperWatcher(const wrapFunc& func)

: func_(func)

{}

void RunInWatcher(int type, int state, const char* path) {

func_(path, type, state);

}

private:

wrapFunc func_;

}/*}}}*/;

void watcher(zhandle_t* zh, int type, int state, const char* path, void* ctx)

{/*{{{*/

ZooKeeperWatcher* watcher = static_cast<ZooKeeperWatcher*>(ctx);

watcher->RunInWatcher(type, state, path);

}/*}}}*/

}//namespace detail

/////////////////////////////////////////////////////////////////////////////////

/**

* 1,set debug level of log

* 2,init zookeeper(connect host and set timeout and callback func)

* 3,if fail then false else true

* \param host indicate zookeeper server lists

* \param fun indicate callback func

* \param timeout indicate timeout of zookeeper

*/

bool ZKOP::zkInit(const std::string& host, const wrapFunc& func, const int timeout)

{/*{{{*/

zoo_set_debug_level(ZOO_LOG_LEVEL_WARN);

context_ = new detail::ZooKeeperWatcher(func); ////////////////////////////使用中间层

zkhandle = zookeeper_init(host.data(),

detail::watcher, ////////////////////中间层的回调

timeout,

&clientid_,

context_,

0);

if (NULL == zkhandle) {

LOG(INFO) << "init zookeeper handle fail!\t"<< "host:" << host;

return false;

}else{

LOG(INFO) << "init zookeeper successful!";

return true;

}

}/*}}}*/

//////////////////////////////////////////////

/*

name=main.cpp

*/

/*

省略代码

pzoo = std::tr1::shared_ptr<ZKOP>(new ZKOP());

*/

bool init_zk(){

bool ret_init = pzoo->zkInit(FLAGS_zk_host,

std::tr1::bind(&ZKOP::zkWatcher, ////////////////////////////绑定回调(像正常类中成员函数一样使用只不过通过中间层弄封的)

*pzoo,

std::tr1::placeholders::_1,

std::tr1::placeholders::_2,

std::tr1::placeholders::_3

),

FLAGS_zk_timeout);

if(false == ret_init){

return false;

}

return true;

}

以上代码仅为片断,可以简单说明使用方法,有问题请指正,多谢

供参考交流
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: