如何在静态函数中使用成员函数数组
How to use member functions array in a static function?
我有一个类,叫做Channel_thread
。正如你所猜测的,它的一个函数是线程化的,在这个函数中,我想根据情况调用另一个成员函数。这就是我使用成员函数数组的原因。
以下是代码的样子:
Channel_thread.cpp:
#include <boost/bind.hpp>
#include "../include/Channel_thread.h"
Channel_thread::Channel_thread(Event_queue<std::deque<char>> *_serverQueue, Event_queue<std::deque<char>> *_messageQueue)
{
serverQueue = _serverQueue;
messageQueue = _messageQueue;
}
void Channel_thread::startThread()
{
isRunning = true;
t = new boost::thread(boost::bind(&Channel_thread::start, this));
}
void Channel_thread::start(void *data)
{
auto *_this = (Channel_thread *)data;
Message *messageReceived = NULL;
while (_this->isRunning)
{
std::pair<std::string, std::deque<char>> p(_this->messageQueue->wait_and_pop());
for (int index = 0; index != 4; index++)
{
if (_this->handlersIndexTab[index] == p.first)
{
messageReceived = _this->handlersTab[index](p.second);
break ;
}
}
}
}
Message *Channel_thread::channelSetupHandler(std::deque<char> bytes)
{
//Do stuff
}
Message *Channel_thread::channelStatusHandler(std::deque<char> bytes)
{
//Do stuff
}
Message *Channel_thread::channelCloseHandler(std::deque<char> bytes)
{
//Do stuff
}
Message *Channel_thread::streamSetupHandler(std::deque<char> bytes)
{
//Do stuff
}
Channel_thread.h
#include <boost/thread.hpp>
#include "Event_queue.h"
#include "Channel_setup.h"
#include "Channel_status.h"
#include "Channel_close.h"
#include "Stream_setup.h"
class Channel_thread {
typedef Message *(Channel_thread::*fn)(std::deque<char>);
public:
Channel_thread(Event_queue<std::deque<char>> *, Event_queue<std::deque<char>> *);
static void start(void *);
void startThread();
Message *channelSetupHandler(std::deque<char>);
Message *channelStatusHandler(std::deque<char>);
Message *channelCloseHandler(std::deque<char>);
Message *streamSetupHandler(std::deque<char>);
private:
Event_queue<std::deque<char>> *messageQueue;
Event_queue<std::deque<char>> *serverQueue;
bool isRunning;
boost::thread *t;
fn handlersTab[4] = {channelSetupHandler, channelStatusHandler, channelCloseHandler, streamSetupHandler};
std::string handlersIndexTab[4] = {"channel_setup", "channel_status", "channel_close", "stream_setup"};
};
我得到这个错误:
/cygdrive/c/Users/foo/CLionProjects/Server_cpp/src/Channel_thread.cpp: In static member function 'static void Channel_thread::start(void*)':
/cygdrive/c/Users/foo/CLionProjects/Server_cpp/src/Channel_thread.cpp:35:69: error: must use '.*' or '->*' to call pointer-to-member function in '_this->Channel_thread::handlersTab[index] (...)', e.g. '(... ->* _this->Channel_thread::handlersTab[index]) (...)'
messageReceived = _this->handlersTab[index](p.second);
正如你所看到的,我在数组中调用成员函数的方式似乎是错误的,可能是因为static
上下文的原因,我真的不知道,所以我的问题是:
如何从静态函数调用存储在成员函数数组中的成员函数?
提前谢谢。
使用_this->handlersTab[index](p.second);
有几个问题。
-
使用成员函数指针的语法与使用成员函数的语法不同。成员函数指针在被调用之前需要取消引用。给出一个成员函数指针
mfPtr
,要使用的语法是(objectPtr->*mfPtr)(...)
。请参阅指向成员函数的指针部分https://en.cppreference.com/w/cpp/language/pointer了解更多详细信息。 -
第二个问题是
handlersTab
不是static
成员变量。要获得指向成员函数的指针,必须使用_this->handlersTab
。
进行函数调用的一行代码是:
messageReceived = (_this->*(_this->handlersTab[index]))(p.second);
我建议用两行来简化它。
fn handler = _this->handlersTab[index];
messageReceived = (_this->*handler)(p.second);
如果您使用的是c++17,最简单的解决方案是在函数头中使用std::invoke。
std::invoke(&Channel_thread::handlersTab[index], this, p.second);
确保handlersTab是静态的。handlersIndexTab也应该是。
根据您的情况,另一种方法是使用枚举而不是字符串作为消息,然后打开枚举并直接调用所需的方法。如果消息完全在您的控制范围内,包括传输通道,则这是最合适的。
如果在消息中包含描述性字符串很重要,那么我看到的另一种方法是打开消息的哈希散列必须是constexpr函数,这样才能在编译时计算您的case值。用法:
switch (hash(p.first))
{
case "channel_setup"_hash:
channelSetupHandler(p.second)
break;
...
default:
// error handling
}
使用这种方法的优点是
- 所需方法的直接调用
- 不需要同步两个列表,事实上既不需要函数列表也不需要查找列表
- 默认情况可用于处理坏消息
- 更透明的代码
- 易于扩展
- 对RValue对象调用的LValue ref限定成员函数
- 为什么使用 "this" 指针调用派生成员函数?
- 将公共但非静态的成员函数与ALGLIB集成
- 使用指向成员的指针将成员函数作为参数传递
- 将重载的成员函数传递给函数模板
- 我不小心调用了一个没有自己类对象的成员函数.但这是怎么回事呢
- 如何在C++中使用非静态成员函数作为回调函数
- C++错误C2600:无法定义编译器生成的特殊成员函数(必须首先在类中声明)
- 关联容器的下界复杂性:成员函数与非成员函数
- 在 C++ 中用派生类型重写成员函数
- 链表的泛型函数remove()与成员函数remove)
- 如何将lambda作为模板类的成员函数参数
- constexpr构造函数需要常量成员函数时出现问题
- 将自由函数绑定为类成员函数
- 区分非成员函数和头文件中的成员函数
- 如何从子成员函数修改父公共成员变量
- 保留对其他类的成员函数的引用
- 在运算符重载定义中使用成员函数(const错误)
- 内联如何影响模块接口中的成员函数
- 将成员函数指针作为参数传递给模板方法