Передача большего количества параметров в указателях функции C

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

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

class Foo {
  public static void method() {
     System.out.println("in Foo");
  }
}

class Bar extends Foo {
   public static void method() {
    System.out.println("in Bar");
  }
}
9
задан Community 9 September 2008 в 21:13
поделиться

8 ответов

А-ч, если только C поддерживаемые закрытия...

Antonio прав; если необходимо передать дополнительные параметры, необходимо будет переопределить указатель функции для принятия дополнительных аргументов. Если Вы не знаете точно, в каких параметрах Вы будете нуждаться, то у Вас есть по крайней мере три варианта:

  1. Имейте последний аргумент в своем прототипе быть void*. Это дает Вам гибкость передачи в чем-либо еще, в чем Вы нуждаетесь, но это определенно не безопасно с точки зрения типов.
  2. Используйте variadic параметры (...). Учитывая мое отсутствие опыта с variadic параметрами в C, я не уверен, можно ли использовать это с указателем функции, но это дает еще больше гибкости, чем первое решение, хотя все еще с отсутствием безопасности типов.
  3. Обновите до C++ и используйте функциональные объекты.
11
ответ дан 4 December 2019 в 07:49
поделиться

Необходимо было бы, вероятно, переопределить указатель функции для взятия дополнительных аргументов.

void foreachMove( void (*action)(chess_move*, int), chess_game* game )
8
ответ дан 4 December 2019 в 07:49
поделиться

Если Вы готовы использовать некоторый C++, можно использовать "функциональный объект":

struct MoveHandler {
    chess_game *game;
    int depth;

    MoveHandler(chess_game *g, int d): game(g), depth(d) {}

    void operator () (chess_move*) {
         // now you can use the game and the depth
    }
};

и поворот Ваш foreachMove в шаблон:

template <typename T>
void foreachMove(T action, chess_game* game);

и можно назвать его как это:

chess_move getNextMove(chess_game* game, int depth){
    //for each valid move, determine how good the move is
    foreachMove(MoveHandler(game, depth), game);
}

но это не разрушит Ваше другое использование MoveHandler.

5
ответ дан 4 December 2019 в 07:49
поделиться

Если бы я читаю это право, что я предложил бы, должен сделать Ваше функциональное взятие указателем на структуру как аргумент. Затем Ваша структура может иметь "игру" и "глубину", когда ей нужны они, и просто оставить их набором 0 или Пустой указатель, когда Вам не нужны они.

Что продолжается в той функции? У Вас есть условное выражение, которое говорит,

if (depth > -1) //some default
  {
  //do something
  }

Функция всегда ТРЕБУЕТ "игры" и "глубины"? Затем они должны всегда быть аргументами, и это может войти в Ваши прототипы.

Вы указываете, что функция только иногда требует "игры" и "глубины"? Ну, возможно, сделайте две функции и используйте каждого, когда Вы должны будете.

Но, имея структуру, поскольку аргументом является, вероятно, самая легкая вещь.

3
ответ дан 4 December 2019 в 07:49
поделиться

Я предложил бы использовать массив пустоты*, с последней записью всегда освобождают. скажите необходимость в 3 параметрах, Вы могли сделать это:

void MoveHandler (void** DataArray)
{
    // data1 is always chess_move
    chess_move data1 = DataArray[0]? (*(chess_move*)DataArray[0]) : NULL; 
    // data2 is always float
    float data1 = DataArray[1]? (*(float*)DataArray[1]) : NULL; 
    // data3 is always char
    char data1 = DataArray[2]? (*(char*)DataArray[2]) : NULL; 
    //etc
}

void foreachMove( void (*action)(void**), chess_game* game);

и затем

chess_move getNextMove(chess_game* game, int depth){
    //for each valid move, determine how good the move is
    void* data[4];
    data[0] = &chess_move;
    float f1;
    char c1;
    data[1] = &f1;
    data[2] = &c1;
    data[3] = NULL;
    foreachMove(moveHandler, game);
}

Если все параметры являются тем же типом затем, можно избежать, чтобы пустота* выстроила и просто отправила ЗАВЕРШЕННЫЙ ПУСТЫМ УКАЗАТЕЛЕМ массив любого типа, в котором Вы нуждаетесь.

1
ответ дан 4 December 2019 в 07:49
поделиться

Используйте определение типа для указателя функции. См. мой ответ для этого вопроса

0
ответ дан 4 December 2019 в 07:49
поделиться

Если бы Ваши параметры изменяются, я изменил бы объявление указателя функции для использования "..." техника для установки переменного количества аргументов. Это могло сохранить Вас в удобочитаемости и также имеющий необходимость внести изменение для каждого параметра, который Вы хотите передать функции. Это определенно намного более безопасно, чем раздавание пусто.

http://publications.gbdirect.co.uk/c_book/chapter9/stdarg.html

Просто к вашему сведению, о примере кода в ссылке: некоторые места, которые они имеют “n args” и другие, это - “n_args” с подчеркиванием. У них должно все быть подчеркивание. Я думал, что синтаксис выглядел немного забавным, пока я не понял, что они отбросили подчеркивание в некоторых местах.

0
ответ дан 4 December 2019 в 07:49
поделиться

+1 Antonio. Необходимо изменить объявление указателя функции для принятия дополнительных параметров.

Кроме того, не начинайте раздавать пустые указатели или (особенно) массивы пустых указателей. Это просто напрашивается на неприятности. Если Вы начинаете передавать пустые указатели, Вы собираетесь также должными быть передать некоторое сообщение для указания на то, что тип указателя (или типы). Эта техника является редко соответствующей.

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

0
ответ дан 4 December 2019 в 07:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: