函数指针如何替换switch语句?

时间:2014-10-16 06:06:27

标签: c++ c pointers function-pointers

我正在阅读关于函数指针的本教程,它说函数指针可以替换switch语句 http://www.newty.de/fpt/intro.html

任何人都可以澄清吗?

我们有这样的开关语句:

// The four arithmetic operations ... one of these functions is selected
// at runtime with a swicth or a function pointer
float Plus    (float a, float b) { return a+b; }
float Minus   (float a, float b) { return a-b; }
float Multiply(float a, float b) { return a*b; }
float Divide  (float a, float b) { return a/b; }


// Solution with a switch-statement - <opCode> specifies which operation to execute
void Switch(float a, float b, char opCode)
{
   float result;

   // execute operation
   switch(opCode)
   {
      case '+' : result = Plus     (a, b); break;
      case '-' : result = Minus    (a, b); break;
      case '*' : result = Multiply (a, b); break;
      case '/' : result = Divide   (a, b); break;
   }

   cout << "Switch: 2+5=" << result << endl;         // display result
}

// Solution with a function pointer - <pt2Func> is a function pointer and points to
// a function which takes two floats and returns a float. The function pointer
// "specifies" which operation shall be executed.
void Switch_With_Function_Pointer(float a, float b, float (*pt2Func)(float, float))
{
   float result = pt2Func(a, b);    // call using function pointer

   cout << "Switch replaced by function pointer: 2-5=";  // display result
   cout << result << endl;
}


// Execute example code
void Replace_A_Switch()
{
   cout << endl << "Executing function 'Replace_A_Switch'" << endl;

   Switch(2, 5, /* '+' specifies function 'Plus' to be executed */ '+');
   Switch_With_Function_Pointer(2, 5, /* pointer to function 'Minus' */ &Minus);
}

如您所见,Replace_A_Switch()函数作为示例非常不清楚。假设我们需要将函数指针指向4个算术函数之一(Plus,Mins,Multiply,Divide)。我们怎么知道我们需要指出哪一个?我们必须再次使用switch语句将函数指针指向算术函数,对吗?

就像这一个**(请在代​​码中注释)**:

void Replace_A_Switch()
{
    .....................
    ..........
    //How can we know this will point to the &Minus function if we don't use the switch statement outside?
    Switch_With_Function_Pointer(2, 5, /* pointer to function 'Minus' */ &Minus);
}

总而言之,函数指针的优点是什么,它总是说函数指针是一种后期绑定机制,但在本教程中我没有看到函数指针有任何优势,可以用于后期绑定。 任何帮助都非常感谢。感谢。

4 个答案:

答案 0 :(得分:2)

你所说的非常正确,你还需要决定使用哪个函数指针。

你所看到的是一个非常简单,人为的例子,用于解释目的。它显示了如何利用函数指针。在这种情况下,它可能是毫无意义的复杂,但真实案例可能太复杂,无法用于指导这个基本概念。

当您拥有许多具有相同开关的功能或具有相同设置子集的开关时,差异会变得更加清晰。虽然差别很大(这也很重要)。在那种情况下,为什么要重写一次?

它还会打开您的代码,以便更改决策方式。也许你想要因为某种原因而反转'+'和' - '。更改制作指针的位置,并抓住所有客户端代码。

最后,如果你甚至不需要做出决定怎么办?例如,如果您只是想要添加版本,而不是更换开关?显然,对于这种设计水平来说,添加是一项过于简单的任务,但这只是一个例子。

无论您使用的是函数指针还是类层次结构,所有这一切都是正确的。有人必须决定输入是什么。这些构造的作用是为您提供一种方法,将不同的位组合成正在运行的程序。它还将负责决定使用哪种版本的东西的部分与使用这些东西分开。有很多不同的方法来处理这种创作(参见一些创作设计模式)。

答案 1 :(得分:1)

正如教程所述,没有任何优势,基本计算器只是一个例子。函数指针的主要用途是允许API-dev定义一个函数,该函数执行API创建时未知的内容。

一个更好的例子可能是qsort,它采用比较函数。由于这个函数指针参数,可以以通用方式实现排序。由于您无法知道需要对哪种数据进行排序,因此您无法了解必须如何实施<,=,>运算符。因此,您希望调用者提供实现比较的函数,从而避免这种困境。

通常,如果要以通用方式编写某些内容,函数指针通常很有用。它的用途是其他语言中的函数参数。例如,如果有人要求你实现一个简单的reduce函数,你可以想出这样的东西:

 void reduce(void *data, size_t nmemb, size_t size,
        void (*op)(void *, void *), void *res){
                int i;
                for (i = 0; i < nmemb; ++i){
                        op(data, res);
                        data = (void *)((unsigned char*)data + size);
                }
        }

显然,相对于乘法,添加和更复杂的操作重写这一操作非常有利,并且相应的函数替换op。

答案 2 :(得分:0)

我可以看到如何将'+',' - '等转换为enum,并将4个func指针存储到按enum顺序排序的数组中。在那之后arr[op]是你想要的功能,只需执行它。

或者来自std::map<String, FuncType>的{​​{1}}地图 - &gt; +

答案 3 :(得分:-1)

从我所看到的......

pt2Func 是为引用函数的指针定义的名称

你可以看到它在主要调用方式中的工作原理 (删除了评论以使其更具可读性)

Switch_With_Function_Pointer(2, 5, &Minus);

&amp; Minus 这里是一个引用你的功能的指针减号

这是愚蠢的,因为您正在调用函数来使用指针引用另一个函数。 没有任何好处,它没有什么特别的......它只是另一种更复杂的方式来调用减号功能

然而,开关功能只是一个封装在可重用功能中的普通开关