Указатель функции базового класса указывает на функцию-член дочернего класса? - PullRequest
3 голосов
/ 13 октября 2010

Я знаю, это звучит ужасно запутанно, у меня есть базовый шаблонный класс, который имеет указатель на функцию, дочерний класс (который больше не является классом шаблона) должен использовать этот указатель на функцию, чтобы указывать на функцию-член дочернего класса, и Я получаю все виды ошибок .. Я нарушил какой-то универсальный закон C ++? вот псевдокод:

template <class T>
class Base{
    public:
       typedef void (Base<T>::*fptr) (char in);
       void funcA(fptr FuncToCall){
                 FuncToCall('a');
       }
       ...
    };

class Child:public Base<char>{
   public: 
       void funcToCall(){...}
       void funcB(){
          funcA(funcToCall);
       }
}

Вот сообщение об ошибке, которое я получил:

ошибка C2664: «База :: funcA»: невозможно преобразовать параметр 1 из 'void (__thiscall Child :: *) (char) 'to' void (__thiscall Base :: *) (char) '

1 Ответ

9 голосов
/ 13 октября 2010

Ваш код недействителен.

Во-первых, в C ++ для создания указателя на функцию-член вам всегда необходимо использовать оператор & и квалифицированное имя члена,это означает, что ваш вызов funcA должен выглядеть следующим образом

funcA(&Child::funcToCall); // close, but not yet, see "secondly" 

Во-вторых, указатели на элементы контравариантны .Если вы хотите инициализировать объект указателя на базовый член значением указателя на производный член, вы должны использовать явное static_cast

funcA(static_cast<fptr>(&Child::funcToCall));

Обратите внимание, что это допустимое, но потенциально небезопасное преобразование, поскольку онотеперь вы несете ответственность за то, чтобы фактический объект, используемый в левой части вызова (см. «в-третьих»), имел этот член.

В-третьих, для вызова функции через такой указатель вынеобходимо указать конкретный объект с левой стороны, поэтому вызов в funcA должен выглядеть следующим образом (я предполагаю, что вы хотите вызвать его для *this объекта)

(this->*FuncToCall)('a');

В-четвертых,ваш funcToCall должен иметь параметр.Где это?

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