Каков синтаксис для вызова указателя на функцию-член, которая является членом структурного массива в C ++ - PullRequest
1 голос
/ 13 марта 2012

Этот вопрос похож на то, что я пытаюсь сделать Вызов указателя на функцию-член C ++ из структуры .Однако моя структура содержит указатель на функцию-член, который определен в другом классе, чем тот, в котором структура определена и используется. Вот пример кода того, как размечаются мои классы, структуры и указатели на функции.

// Alpha.h:
class Alpha{
public:
    void function1(char name[], int number);
    void function2(char name[], int number);
    void function3(char name[], int number);

    typedef void (Alpha::*My_func_ptr)(char name[], int number);

    static My_func_ptr functionTable[];
};

// Alpha.cpp:
#include "Alpha.h"

Alpha::My_func_ptr Alpha::functionTable[] = {
    &Alpha::function1, 
    &Alpha::function2, 
    &Alpha::function3
};

void Alpha::function1(char name[], int number)
{
    //some stuff
}

void Alpha::function2(char name[], int number)
{
    //some stuff
}

void Alpha::function3(char name[], int number)
{
    //some stuff
}

// Beta.h:
#include "Alpha.h"

typdef struct{
    char bName[10];
    Alpha::My_func_ptr fptr;
}ptr_structure;

class Beta{
public:
      void betafunction();

      Alpha alphaobject;
      ptr_structure str_array[3];
};

// Beta.cpp:
#include "Beta.h"

void betafunction()
{
    str_array[0].fptr = alphaobject.functionTable[0];
    str_array[1].fptr = alphaobject.functionTable[1];
    str_array[2].fptr = alphaobject.functionTable[2];

    (str_array[0].fptr)("name", 1); //gives error expression must have 
                                    //(pointer-to-)  function type

    (this->*str_array[0].fptr)("name", 1);
    //error pointer-to-member selection class types are incompatible "Beta" and "Alpha"

    //sample function pointer call using function table from other class,
    //this syntax compiles and runs without error.
    (alphaobject.*Alpha::functionTable[0]("name", 1); 
}

Как видите, я могу вызвать указатель на функцию из массива, но не могу понять, как вызвать указатель на функцию из массива структур.

Ответы [ 3 ]

3 голосов
/ 13 марта 2012

При вызове указателя на функцию-член вам необходимо иметь экземпляр объекта, связанный с этим указателем:

 (alphaobject.*(str_array[0].fptr))("name", 1)
  ^^^^^^^^^^^
0 голосов
/ 13 марта 2012

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

void Beta::betafunction() {
   Alpha a;
   (a.*(strArray[0].fptr))("name",1);
}

Но я бы на самом деле попытался сделать вещи немного проще:

void Beta::betafunction() {
   Alpha a;
   Alpha::My_func_ptr mptr = strArray[0].fptr;
   (a.*mptr)("name",1);
}

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

0 голосов
/ 13 марта 2012

Я бы подумал:

(object.*functionTable[0])(args, ...);
(objptr->*functionTable[0])(args, ....);

IIRC, комбинация object и оператора .* подобна большому унарному оператору. Так что это имеет более низкий приоритет перед постфиксом [0]. Однако он также имеет более низкий приоритет, чем оператор постфикса вызова функции (args, ...)

Аналогия:

(*foo)();  /* classic C */

Конечно, оператор * не требуется при вызове обычной функции. Но если вы пишете это, вам нужны парены, потому что *foo() означает что-то еще.

...