2014-09-12 2 views
-2

Может ли кто-нибудь объяснить мне преимущества функции poiner?Преимущества функции указателя

Я знаю, что есть много возможных дубликатов с моим вопросом, но они только объясняют словами, это не очень полезно, мне нужен пример случая, когда не используется указатель функции, сравнивается с случаем использования указателя функции.

Большое спасибо.

+4

Что вы подразумеваете под «преимуществом»? Указатель функции - это еще один инструмент, который вы можете использовать, вот и все. Они позволяют делать то, что невозможно сделать с другими языковыми инструментами. Спросить о своих «преимуществах» примерно так же бессмысленно, как спрашивать о «преимуществе заявления' if' ». – dasblinkenlight

+0

1. Вы можете изменить функцию, на которую указывает указатель. 2. Вы можете сделать указатель массива указателей функции. – GingerPlusPlus

+0

Эти «преимущества» при использовании указателей функций могут различаться в зависимости от того, что вы пытаетесь сделать, и с каким другим параметром вы сравниваете – dseminara

ответ

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 
0

Простой пример: предположим, у вас есть 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) { } 
0

С помощью указателя на функцию вы можете, например, предотвратить дублирование кода.

без указателей на функции:

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 есть лямбда-функции, и они делают все это еще более удобным.

0

Ключевым моментом является то, что указатели на функции используются «под капотом» все время в общем программировании. Один имеет тенденцию забывать об этом, потому что аргумент аргумента шаблона скрывает синтаксис указателя функции.

Например:

#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); 
} 

f в main «s последней строке является функцией указатель, так как функция 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 может быть указателем на функцию, и является одним в приведенном выше примере.

Компилятор просто выводит свой точный тип, bool(*)(int), автоматически, когда вы проходите f.Технически, вы могли бы также написать вызов, как это:

// 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()); 
} 
Смежные вопросы