Есть ли способ определить во время выполнения, может ли объект выполнять метод на С++?

В Perl есть метод UNIVERSAL::can, который вы можете вызвать для любого класса или объекта, чтобы определить, может ли он что-то сделать:

sub FooBar::foo {}
print "Yup!\n" if FooBar->can('foo'); #prints "Yup!"

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

РЕДАКТИРОВАТЬ: Подождите, теперь это очевидно (не говоря уже о вопросе), я мог бы просто реализовать его в базе, которая возвращает число, представляющее UNIMPLEMENTED, а затем проверить, что возврат не является таким, когда вы его вызываете. Я не уверен, почему я думал о вещах таким сложным образом.

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


person Jake    schedule 03.09.2009    source источник
comment
Это то же самое, что и: stackoverflow.com/questions/87372/   -  person fbrereto    schedule 03.09.2009
comment
Имейте в виду, что функция должна быть виртуальной, чтобы ваше решение работало.   -  person David Thornley    schedule 10.09.2009


Ответы (4)


Если у вас есть указатель или ссылка на базовый класс, вы можете использовать dynamic_cast, чтобы увидеть, какой это производный класс (и, следовательно, какие методы производного класса он поддерживает).

person ChrisW    schedule 03.09.2009

Если вы можете добавить методы в базовый класс, вы можете добавить virtual bool can_foo() {return false;} и переопределить его в подклассе, у которого есть foo, чтобы он возвращал true.

person sepp2k    schedule 03.09.2009

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

person Eclipse    schedule 03.09.2009

Я считаю, что наиболее правильным способом было бы использовать оператор typeid‹> и получить ссылку на объект type_info, а затем вы могли бы сравнить этот (== оператор) с желаемым type_info для типов данных, о которых вы хотите заботиться.

Это не дает вам проверки на уровне метода и требует, чтобы вы построили с включенным RTTI (я полагаю, что использование typeid‹> для объекта, который был создан без RTTI, приводит к «неопределенному» поведению), но вот вы .

В MSDN есть онлайн-справочник, который поможет вам начать работу: http://msdn.microsoft.com/en-us/library/b2ay8610%28VS.80%29.aspx

person ted_j    schedule 03.09.2009