用c ++实现消息

时间:2016-05-16 03:43:24

标签: c++

如您所知,objective-c使用消息表达式来调用成员函数(方法),这意味着您可以在运行时动态调用成员函数。 我想在c ++中将此消息表达式实现为类。因此,任何类都可以通过继承和注册其成员函数来使用消息表达式。 这是我正在尝试做的简单示例。

enter image description here

在SomeClass.cpp中

// class SomeeClass : public MyMessageExpression

type SomeClass::method_name_of_SomeClass(){
   //code..
   registerFunc(method_name_of_SomeClass) //registerFunc will add the function pointer into the function table  
}

最后你可以这样使用,

SomeClass.sendMessge("method_name_of_SomeClass");

我无法解决的问题是我将如何在运行时将void指针强制转换为mothod_name_of_SomeClass的函数指针。如何在函数表中设置变量函数指针?

如果mothod_name_of_SomeClas使用stdcall调用约定我该如何实现这个类?

2 个答案:

答案 0 :(得分:1)

所以基本上你有几个层次可以解决这个问题......

  1. 忽略它,当在罗马做罗马时,使用virtual方法和c ++范例
  2. 使用Objective-C ++,这在Mac OSX gui和c ++库之间作为垫片非常有用
  3. 使用字符串作为选择器......并且模拟出NSInvocation,使用类似MyObject::performMethodWithArguments(std::string methodName, ...)的可变方法...这将是逻辑沉重且有点痛苦
  4. 可能只是了解虚拟方法和函数指针。

答案 1 :(得分:1)

以下内容适合您:

#include <map>
#include <iostream>

template<typename C>
struct MessageExpression
{
    std::map<std::string,void(C::*)(void)> functions;
    void registerFunc(std::string name,void(C::*function)(void))
        { functions[name]=function; }
    void sendMesg(std::string name)
        { (static_cast<C*>(this)->*functions[name])(); }
};

struct SomeClass : public MessageExpression<SomeClass>
{
    void method1() { std::cout << "method1" << std::endl; };
    void method2() { std::cout << "method2" << std::endl; };
};

int main()
{
    SomeClass s;
    s.registerFunc("method1",&SomeClass::method1);
    s.registerFunc("method2",&SomeClass::method2);
    s.sendMesg("method1");
    s.sendMesg("method2");
}

您可以将void指针存储在void指针数组中,但在某些时候您需要将其转换回正确的成员函数指针。因为无论如何都要在MessageExpression中完成,你也可以在正确的地图中存储正确类型的指针。

你需要将&amp; SomeClass :: method1传递给registerFunc,因为编译器不知道method1,除非你说它在哪个命名空间。我也传递字符串 - 你可以使用预处理器宏来进行字符串化如果需要,可以使用函数名称。

您可以做的另一件事是在地图中存储std :: function。但是之后你需要在调用之前绑定this指针。我没有看到这里的优势 - 如果你将这个指针绑定到地图之前可能会更有意义。