C ++ «Неполный тип не разрешен», пытающийся создать массив функций внутри класса - PullRequest
0 голосов
/ 15 марта 2020

Как получить приведенный ниже пример кода, который компилируется и прекрасно работает для работы внутри класса?


Ниже код работает просто отлично

#include <iostream>
using namespace std;

typedef int (*IntFunctionWithOneParameter) (int a);

int function(int a){ return a; }
int functionTimesTwo(int a){ return a*2; }
int functionDivideByTwo(int a){ return a/2; }

void main()
{
    IntFunctionWithOneParameter functions[] = 
    {
        function, 
        functionTimesTwo, 
        functionDivideByTwo
    };

    for(int i = 0; i < 3; ++i)
    {
        cout << functions[i](8) << endl;
    }
}

Таким образом, приведенный выше код работает нормально, но я хочу переместить его в класс в отдельный файл, аналогично приведенному ниже НЕРАБОЧНОЙ ИДЕЕ, где я получаю «неполный тип не допускается» ошибка в «functions [] =»;

class myClass {
private:

  typedef int (*IntFunctionWithOneParameter) (int a);

  int function(int a){ return a; }
  int functionTimesTwo(int a){ return a*2; }
  int functionDivideByTwo(int a){ return a/2; }

  IntFunctionWithOneParameter functions[] = 
    {
        function, 
        functionTimesTwo, 
        functionDivideByTwo
    };
};

Поэтому мой вопрос - как мне заставить его работать внутри моего класса, где это ЕДИНСТВЕННОЕ место, где нужны функции, то есть мне нужен доступ к функциям в main () или других местах!


РЕДАКТИРОВАТЬ

Вот почему мне нужен "массив функций". Чтобы сэкономить время, затрачиваемое на «если» или, точнее, на «переключатели», когда я делаю программный (vst) синтезатор, и чем меньше времени затрачивается на обработку, тем больше нот (полифония c) пользователь может воспроизводить в любой момент время. И умножьте 44100 раз в секунду, которую выполняет функция, на 8 тональных генераторов, каждый из которых может иметь до 16 унисонных голосов, так что на самом деле нужная функция может вызываться до 5 644 800 раз в секунду на каждую сыгранную ноту! Точная функция, необходимая внутри этой основной l oop, известна ДО ввода l oop и изменяется ТОЛЬКО, когда пользователь настраивает ручку, поэтому я хочу избегать переключений и переключателей. Теперь, если бы только одна функция периодически менялась, я мог бы просто дублировать основной l oop с вариациями для каждой возможной функции, ОДНАКО основная обработка звука l oop имеет несколько областей, каждая из которых имела множество постоянно растущих возможных функций. каждая из которых изменяется ТОЛЬКО при смене пользователем различных ручек. Поэтому, хотя я мог бы, я не собираюсь делать 5 * 20 * 23 (и растущих) различных версий основного l oop, чтобы избежать переключателей if и.

Ответы [ 3 ]

1 голос
/ 15 марта 2020

В коде, который вы разместили, есть что-то не так:

  • Нет точки с запятой после определения класса.
  • Class вместо class
  • Не задан фиксированный размер для элемента functions, что недопустимо. Вам необходимо явно установить размер массива.
  • Указатели на функции-члены не совпадают с «обычными» указателями на функции. Указатели на функции-члены имеют неявный this в качестве первого аргумента, поскольку они нуждаются в вызове объекта. Так что myFunction не относится к типу myArrayOfFunctions. Если вы сделаете myFunction и myFunction2 stati c, то они могут быть сохранены как обычные указатели функций. Это опция?
  • Имя myArrayOfFunctions очень сбивает с толку, поскольку это вообще не массив.

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

0 голосов
/ 15 марта 2020

Вы можете написать это:

class myClass
{
public:
    typedef float (*myArrayOfStaticFunctions) (int& a, int& b, float& c);
    typedef float (myClass::*myArrayOfFunctions) (int& a, int& b, float& c);

    static float myFunction1 (int& a, int& b, float& c){cout<<"myFunction1"<<endl; return 0;}
    static float myFunction2 (int& a, int& b, float& c){ cout<<"myFunction2"<<endl; return 0;}
    float myFunction3 (int& a, int& b, float& c){ cout<<"myFunction3"<<endl; return 0;}
    float myFunction4 (int& a, int& b, float& c){ cout<<"myFunction4"<<endl; return 0;}

    myArrayOfStaticFunctions    StaticArrayfunctions[2];
    myArrayOfFunctions          Arrayfunctions[2];

    myClass (){
        StaticArrayfunctions [0] =myFunction1;
        StaticArrayfunctions [1] =myFunction2;
        Arrayfunctions [0] = &myClass::myFunction3;
        Arrayfunctions [1] = &myClass::myFunction4;
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
    myClass m;
    int a =0, b=0; float c;

    m.StaticArrayfunctions[0] (a,b,c);
    m.StaticArrayfunctions[1] (a,b,c);

    myClass::myArrayOfFunctions func3 = m.Arrayfunctions[0];
    myClass::myArrayOfFunctions func4 = m.Arrayfunctions[1];

    (m.*func3)(a,b,c);
    (m.*func4)(a,b,c);

    return 0;
}
0 голосов
/ 15 марта 2020

Этот пример может быть тем, что вам нужно.

Примечание: я изменил оператор typedef на using и изменил сигнатуры функций, чтобы они принимались в виде простого int для проверки удобства sake.

class myClass {
public:
    using myArrayOfFunctions = float(myClass::*)(int a, int b, float c);

    float myFunction1 (int a, int b, float c)
    {
        return a * b * c;
    }

    float myFunction2 (int a, int b, float c)
    {
        return a + b + c;
    }

    myArrayOfFunctions functions[2];

    myClass()
    {
        functions[0] = &myClass::myFunction1;
        functions[1] = &myClass::myFunction2;
    };

    void Invoke()
    {
        (this->*functions[0])(1, 2, 3);
        (this->*functions[1])(3, 2, 1);
    }
};

int main()
{
    myClass a;
    a.Invoke();
    (a.*(a.functions[0]))(4, 5, 6);
    return 0;
}

Как видите, я получаю указатель на функцию класса, но для ее вызова мне нужно вызвать ее с реальным объектом (this в функции invoke () и a объект в main ()).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...