Функция проверки С++ перегружена или не во время выполнения

У меня есть абстрактный интерфейс I, в котором определена virtual void Foo() вместе с другими функциями. Есть некоторые подклассы, в которых Foo переопределен, и другие, в которых Foo нет. Теперь, учитывая I* pi, можно ли узнать, переопределено ли Foo? То есть я хочу знать, будет ли pi->Foo() вызывать I::Foo() или X::Foo(), где X — это какой-то тип, в котором Foo переопределяется. Я думаю, что это можно сделать, сравнив указатели функций между &I::Foo и &pi->Foo, но точно не знаю, как это сделать. Обратите внимание, что я не знаю конкретный тип pi во время выполнения, поэтому я не могу напрямую сравнивать указатели функций по &I::Foo != &X::Foo.

ДОБАВИТЬ: Итак, многие люди указали, что дизайн плохой, в отличие от концепции абстракции и виртуальных функций. Основная причина, по которой я это делаю, — обход пустых вызовов функций для повышения скорости. Поскольку некоторые из Foo() пусты, я хотел бы удалить их из вектора pis, когда Foo() пусто.


person xosp7tom    schedule 04.01.2012    source источник
comment
Почему? Если вы вызовете функцию, вы увидите, заканчивается ли она I::foo. Тогда ты узнаешь!   -  person Bo Persson    schedule 04.01.2012
comment
Из любопытства, почему вы хотите это сделать? Я чувствую запах плохого дизайна.   -  person Benjamin Lindley    schedule 04.01.2012
comment
Насколько я знаю, вы не можете сохранить результат динамической отправки. У меня был вопрос в какой-то момент. Однако вы можете сделать это в Objective-C++.   -  person Kerrek SB    schedule 04.01.2012
comment
Разве весь смысл абстракции не не в том, чтобы знать это? Зачем тебе это?   -  person littleadv    schedule 04.01.2012
comment
Нет, ты не можешь. И вы не должны.   -  person Cat Plus Plus    schedule 04.01.2012
comment
Это было бы полезно и мне.   -  person Seth Carnegie    schedule 04.01.2012


Ответы (2)


Вы не можете узнать из &pi->Foo, так как, как сообщит вам сообщение об ошибке GCC,

ISO C++ запрещает использование адреса связанной функции-члена для формирования указателя на функцию-член.

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

person Fred Foo    schedule 04.01.2012
comment
Даже если вы используете typeid, вы не можете сказать, переопределена ли функция - person Seth Carnegie; 04.01.2012
comment
@SethCarnegie: нет, но вы можете перечислить типы, которые переопределили функцию. - person Fred Foo; 04.01.2012

Вы можете dynamic_cast указать свой указатель на каждый из дочерних типов, который переопределяет Foo, и если это один из этих типов, он вызовет дочерний. Вы не можете получить адрес функции-члена, используя синтаксис ->, который вы хотите использовать.

Но все это говорит о том, что я бы действительно переосмыслил ваш дизайн, прежде чем делать что-то подобное. Смысл интерфейсов и виртуальных методов в том, чтобы избежать необходимости знать, с каким типом вы имеете дело!

person Mark B    schedule 04.01.2012