【问题标题】:The advantages of function pointer [closed]函数指针的优点
【发布时间】:2014-09-12 16:03:34
【问题描述】:

谁能解释一下函数指针的优点?

我知道我的问题有很多可能的重复,但他们只用文字解释,这不是很有帮助,我需要一个例子来说明不使用函数指针的情况与使用函数指针的情况相比。

非常感谢。

【问题讨论】:

  • “优势”是什么意思?函数指针只是您可以使用的另一个工具,仅此而已。它们让你做其他语言工具无法做到的事情。询问其“优势”与询问“if 声明的优势”大致相同。
  • 1.您可以更改指针指向的函数。 2. 可以创建一个函数指针数组。
  • 这些使用函数指针的“优势”可能会根据您要执行的操作以及您要比较的其他选项而有所不同

标签: c++ function pointers function-pointers


【解决方案1】:

如何将数据映射到行为,例如:

void DoIt();
void DontDoIt();
std::map<std::string, std::function<void()> word_map {
     {"DoIt", DoIt}, 
     {"DontDoIt", DontDoIt}
};
std::string word;

// ... get "DoIt" or "DontDoIt" into word

word_map[word](); // execute correct function

【讨论】:

    【解决方案2】:

    简单示例:假设您有 N 条记录,包括姓名和电话号码。

    你被要求排序

    • 基于名称
    • 基于电话号码

    一个不错的方法是在排序例程中改变作为函数指针传递的比较函数。

    void sort( records r[], int N, 
               bool (*fptr)( const record& lhs, const record& rhs ) ) { }
    

    如果你不使用函数指针,你最终只会为两个不同的比较函数编写相同的逻辑。

    void sort_by_name( records r[], int N) {  }
    
    void sort_by_phoneno( records r[], int N) {  }
    

    【讨论】:

      【解决方案3】:

      例如,通过使用函数指针,您可以防止代码重复。

      没有函数指针:

      void AddOneToVectorElements( vector<int> v )
      {
          // implementation
      }
      
      void MultiplyVectorElementsByTwo( vector<int> v )
      {
          // implementation
      }
      
      // usage
      AddOneToVectorElements(v);
      MultiplyVectorElementsByTwo(v);
      

      使用函数指针:

      typedef int (*func)(int);
      
      int TransformVecotr ( vector<int> v, func f)
      {
          // implementation by application of f to every element
      }
      
      int AddOne(int x)
      {
          return x + 1;
      }
      
      int MultiplyByTwo(int x)
      {
          return 2 * x;
      }
      
      // usage
      TransformVecotr(v, &AddOne);
      TransformVecotr(v, &MultiplyByTwo);
      

      在 C++11 中有 lambda 函数,它们使整个事情变得更加方便。

      【讨论】:

        【解决方案4】:

        关键是函数指针在泛型编程中一直“在后台”使用。人们往往会忘记这一点,因为模板参数推导隐藏了函数指针语法

        例如:

        #include <algorithm>
        #include <iterator>
        
        bool f(int i)
        {
            return i == 1;
        }
        
        int main()
        {
            int arr[] = { 1, 1, 3 };
            int count = std::count_if(std::begin(arr), std::end(arr), f);
        }
        

        main 的最后一行中的f是一个函数指针,因为std::count_if 模板函数将接受任何可以与() 语法一起使用的东西。引用cppreference.com:

        template< class InputIt, class UnaryPredicate >
        typename iterator_traits<InputIt>::difference_type
            count_if( InputIt first, InputIt last, UnaryPredicate p );
        

        UnaryPredicate可以是一个函数指针,在上面的例子中就是一个。

        编译器只是在您传递f 时自动推断出它的确切类型bool(*)(int)。从技术上讲,您也可以这样编写调用:

        // just for illustration:
        std::count_if<int*, bool(*)(int)>(std::begin(arr), std::end(arr), f);
        

        如果 C++ 中没有函数指针,那么您不能直接将函数用作标准库算法中的谓词。相反,您必须始终将它们包装在类中:

        #include <algorithm>
        #include <iterator>
        
        bool f(int i)
        {
            return i == 1;
        }
        
        struct Functor
        {
            bool operator()(int i) const
            {
                return f(i);    
            }
        };
        
        int main()
        {
            int arr[] = { 1, 1, 3 };
            int count = std::count_if(std::begin(arr), std::end(arr), Functor());
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-01-07
          • 1970-01-01
          • 2019-11-16
          • 1970-01-01
          • 1970-01-01
          • 2016-10-27
          相关资源
          最近更新 更多