Почему я не могу заполнить указатель на функцию этого класса функцией этого другого класса - PullRequest
1 голос
/ 27 января 2012

А как насчет указателя на функцию класса на функцию другого класса? Это мой вопрос

Пример:

class Apple
{
   int(Apple::*pActionFunc)(void);
};

class Tree
{
   Apple* tempy;

   void Init( void );

   int I_Work( void );
};

void Tree::Init( void )
{
  tempy = new Apple( );
  tempy->pActionFunc = &Tree::I_Work;
}

int Tree::I_Work( void )
{
   "Do Things"
}

Это не сработает. Почему это?

Ответы [ 4 ]

5 голосов
/ 27 января 2012

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

int(Apple::*pActionFunc)(void); 

Сообщает компилятору, что pActionFunc является указателем на функцию-член класса Apple, которая принимает void в качестве параметра и возвращает int.

tempy->pActionFunc = &Tree::I_Work;

Пытается сохранить адрес функции I_Work(), которая является членом Tree класса an, который принимает void в качестве входного параметра и возвращает int.

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

1 голос
/ 27 января 2012
void foo(int);
void (*pfunc)(double);
pfunc = foo;           // This is an error

Почему это ошибка?Потому что pfunc принимает другой параметр, чем foo.Это то же самое, что здесь происходит.Может показаться, что Tree::I_Work - это функция, которая не принимает параметров и возвращает int, поэтому она должна быть совместимой с функцией Apple, которая не принимает параметров и возвращает int.Но это не так.Вы не можете позвонить в I_Work следующим образом:

x = I_Work();

Можете ли вы?Нет. Вам нужен объект Tree.

a_tree.I_Work();

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

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

0 голосов
/ 27 января 2012

Каждая функция-член имеет невидимый параметр this, который является частью сигнатуры функции.Когда вы пишете:

int(Apple::*pActionFunc)(void);

Внутренне компилятор обрабатывает его как:

int(*pActionFunc)(Apple* this);

Функция, которую вы пытаетесь вставить в указатель, имеет следующий сигнатурный эквивалент:

int I_Work(Tree* this);

Подписи не совпадают.

0 голосов
/ 27 января 2012

В дополнение к тому, что сказал Алс, вы не можете назначить следующее:

tempy->pActionFunc = &Tree::I_Work;

Поскольку I_Work имеет неявный указатель this в качестве аргумента, и поэтому списки аргументов не совпадают.

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