0

Я хочу создать массив указателей статической функции, чтобы я мог перейти к определенной функции относительно полученного индекса. Как индексная перемычка.C++ Инициализация массива указателей статической функции

Так себе класс, как это:

Class A 
{ 
    private: 
    static void 1stFunction(); 
    static void 2ndFunction(); 

    static void(*functionPointer[20])(void); 

}; 

Тогда я хотел бы, что functionPointer получить значение 1stFunction и 2ndFunction, и, возможно, даже больше. Итак, как мне его инициализировать? Насколько я знаю, когда объявлен статический член, вы можете использовать его еще до создания экземпляра. Так что я, хотя, позволяет инициализировать эту указатель на функцию, поэтому позже я могу назвать это как этот

functionPointer[receivedIndex](); 

Так я пытался initilize это так, в том же самом файле .h

void (*A::functionPointer[])(void) = 
{ 
    A::1stFunction, 
    A::2ndFunction, 
}; 

Но компилятор дает мне уточнение, он говорит, что он уже создан.

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

Любая помощь будет оценена по достоинству. Спасибо

+2

[Невозможно воспроизвести] (http://coliru.stacked-crooked.com/a/b190ad02af50c68a), пожалуйста, отправьте сообщение [mvce] (http://stackoverflow.com/help/mcve). – TartanLlama

+0

'A' отличается от' streamHandler', не так ли? – harper

+0

Это все еще не mvce. Почтовый код без ошибок синтаксиса, который отображает проблему, с которой вы столкнулись. – TartanLlama

ответ

4

Следующий пример будет рабочим примером, который, вероятно, достигнет того, что вам нужно.

Для списка инициализаторов необходим C++11.

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

Вы можете позвонить callf с помощью нужного index и вызвать соответствующую функцию, основанную на инициализации массива указателей функций.

Выход программы будет:

I am 2ndFunction 

Заголовок файла

class A 
{ 
private: 
    static void Function1(); 
    static void Function2(); 

    static void(*functionPointer[20])(); 

public: 
    static void callf(int index); 
}; 

осуществления

#include <iostream> 
#include "ex.h" 

void(*A::functionPointer[20])() { 
    A::Function1, 
    A::Function2 
}; 

void A::Function1() { 
    std::cout << "I am 1stFunction" << std::endl; 
} 

void A::Function2() { 
    std::cout << "I am 2ndFunction" << std::endl; 
} 

void A::callf(int index) { 
    A::functionPointer[index](); 
} 

int main(int argc, char const *argv[]) { 
    A::callf(1); 
    return 0; 
} 
+0

Благодарим вас за ответ. Но это дает мне нерешенный внешний символ для A :: Function1 и A :: Function2 –

+0

@WerBn убедитесь, что вы связываете все ваши объектные файлы вместе. – Quentin

+0

@WerBn вам нужно связать файл объекта, в котором вы * определяете * эти функции, –

2

Здесь у вас есть более современный C++ подход (C++ 14 необходимо) Я бы посоветовал вам изучить лямбда-функции, если вы не ограничены C++ 03.

#include <iostream> 
#include <functional> 
#include <vector> 

class A { 
public: 

    using f_type = std::function<void(void)>; 
    f_type f1 = []() { std::cout << "f0" << std::endl;}; 
    f_type f2 = []() { std::cout << "f1" << std::endl;}; 
    static void f3() { std::cout << "f3" << std::endl; } 

    std::vector<f_type> functions{f1, f2, f3}; 

}; 


int main() { 

    A a; 
    a.functions[0](); 
    a.functions[1](); 
    //adding custom lambda 
    a.functions.emplace_back([](){ std::cout << "custom f" << std::endl;}); 
    a.functions[2](); 

    return 0; 
} 

Вы можете добавить обе функции и лямбды в свой контейнер.

+1

Использование 'std :: function' здесь невероятно переполнено. – Quentin

+0

это более читаемо, и это позволит ему легко использовать stl-алгоритмы в своих контейнерах указателей на функции. Если вы не находитесь в среде, где наносекунды имеют значение, я бы не пошел по маршруту указателей функций. Я никогда не пойму, почему люди так неохотно подходят к новым современным способам кодирования. –

+0

'using f_type = void (*) (void)' на самом деле не может сказаться, чтобы ухудшить читаемость, на мой взгляд, и std-алгоритмы отлично работают с указателями функций. 'std :: function' не является« современным указателем функции »(независимо от того, что означает это число), это контейнер стилизованного типа. – Quentin

Смежные вопросы