一个类的映射函数 [英] Map functions of a class

查看:139
本文介绍了一个类的映射函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我尝试映射我的类和命名空间之前,通过使用静态调用,我已经成功了,现在我需要映射我的类的函数,因为它们将被动态使用。



首先,我正在考虑在构造函数中进行硬编码,所以我可以使用指向函数本身的函数名称的字符串来分配一个std:map。



例如:

  class A {
int B(){
return 1;
}
};

int main(){
A * a = new A();
vector< string,int(*)()> VEC;

vector [A.B] = a.B;
}

我已经将A函数映射到A类,我知道我只映射了该实例的功能,并且该B不是静态的以进行全局映射。



但是,我需要的是,某些人会给我一个字符串,我必须调用类的一个实例的正确功能。



我的问题是如果我只能在构造函数中通过hardcoding来做到这一点,因为这是我们正在谈论的一个实例范围,或者是在某种程度上有一种方法来在函数的声明中这里是命名空间和类:



以某种方式在列表中注册我的课程

解决方案

如果我正确理解你,映射以存储可用于调用实例上的成员函数的指针,该值在运行时从映射中选择。我要假设这是正确的事情,而且没有一个更简单的方法来解决同样的问题。很多时候,当你最终在奇怪的C ++回水中,这是一个迹象,你需要再次考虑你认为的问题,看看这是否是解决它的唯一方法。



使用普通函数指针的问题是非静态成员函数不是普通函数。假设你可以使用一个普通的函数指针指向一个成员函数,当你引用那个指针并调用函数时,会发生什么?成员函数需要一个对象进行操作,并且语法不提供传递此对象的方法。



您需要一个指向成员的指针,这是一个稍微模糊的功能与相对棘手的语法。当一个普通的指针抽象一个对象时,一个指向成员的指针抽象一个类上的一个成员;该指针指定哪个类成员应该被调用,而不是从哪个对象获取成员(当使用指针时将被指定)。我们可以使用这样的东西:

  class B; 

class A
{
B some_function()
{/ * ... * /}
};


B(A :: * myval)()= A :: some_function;

这里myval是一个变量,表示A类成员之一,在这种情况下是成员some_function (虽然它可以指向同一类型的A的任何其他成员)。我们可以通过我们想要的任何地方(例如将它存储在STL容器中,如您的示例),然后当我们要调用该函数时,我们指定应该调用的实例来定位函数:

  A some_a; 

B newly_created_b =(some_a。* myval)();

这适用于特定的情况,但它不会解决您的一般问题,因为成员指针包含他们将这些指定为定义的一部分。也就是说,以下两个变量是完全不同的类型:

  B(Foo :: * first_variable)()= Foo: :some_function; 
B(Bar :: * second_variable)()= Bar :: some_function;

即使两个函数都可以在没有参数的情况下调用时产生一个B,这两个值在不同的类和因此,您不能将一种类型的值分配给其他类型的变量。这当然会排除将这些不同类型存储在单个STL容器中。



如果您承诺将这些存储在容器中,则必须使用像查尔斯·萨尔维亚的基于函子的解决方案提出。


Before I was trying to map my classes and namespaces, by using static calls I succeded and now I need to map the functions of my classes because they will be used dynamically.

Firstly I was thinking to hardcode in the constructor so I can assign a std:map with the string of the name of function pointing to the function itself.

for example:

class A{
  int B(){
      return 1;
  }
};

int main(){
  A *a = new A();
  vector<string, int (*)()> vec;

  vector["A.B"] = a.B;
}

By that I have mapped the function B on A class, I know that I only mapped the function the instance and thats B is not static to be globally mapped.

But thats what I need, at somepoint someone will give me a string and I must call the right function of an instance of a class.

My question is if I only can do that by hardcoding at the constructor, since this is a instance scope we are talking or if there is somehow a way to do this in the declaration of the function, like here for namespaces and classes:

Somehow register my classes in a list

解决方案

If I understand you correctly, you want your map to store a pointer that can be used to call a member function on an instance, the value being chosen from the map at run time. I'm going to assume that this is the right thing to do, and that there isn't a simpler way to solve the same problem. Quite often when you end up in strange C++ backwaters it's a sign that you need to look again at the problem you think you have, and see whether this is the only way to solve it.

The problem with using an ordinary function pointer is that a non-static member function is not an ordinary function. Suppose you could point to a member function with an ordinary function pointer, what would happen when you dereferenced that pointer and called the function? The member function needs an object to operate on, and the syntax doesn't provide a way to pass this object in.

You need a pointer to member, which is a slightly obscure feature with relatively tricky syntax. While an ordinary pointer abstracts an object, a pointer to member abstracts a member on a class; the pointer specifies which class member should be called, but not which object to obtain the member from (that will be specified when the pointer is used). We can use it something like this:

class B;

class A
{
    B some_function()
    { /* ... */ }
};


B (A::* myval)() = A::some_function;

Here myval is a variable that indicates one of the members of class A, in this case the member some_function (though it could point to any other member of A of the same type). We can pass myval round wherever we want (e.g. storing it in an STL container, as in your example) and then when we want to call the function, we specify the instance it should be called on in order to locate the function:

A some_a;

B newly_created_b = (some_a.*myval)();

This works for a particular case, but it won't solve your general issue, because member pointers contain the class they refer to as part of the definition. That is, the following two variables are of entirely different types:

B (Foo::* first_variable)() = Foo::some_function;
B (Bar::* second_variable)() = Bar::some_function;

Even though both functions can produce a B when called without arguments, the two values operate on different classes and therefore you can't assign a value of one type to a variable of the other type. This of course rules out storing these different types in a single STL container.

If you're committed to storing these in a container, you'll have to go with a functor-based solution like Charles Salvia proposes.

这篇关于一个类的映射函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆