1

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

class ParentObject {}; 

class DerivedObject : public ParentObject 
{ 
    void myFunction(){} 
}; 

class OtherDerivedObject 
{ 
    void myOtherFunction(){} 
}; 

и хочет функцию указателя на ParentObject :: * и он в состоянии взять функции из любых производного класса. Моя причина для желания сделать это, у меня есть еще один класс

class functionRegistry 
{ 
    std::map<string, *functionPoint> functionMap; 
} 

и каждый объект (в идеале в ParentObject, но можно сделать индивидуально в производных объектов, если необходимо) иметь экземпляр functionRegistry, и мне нужно functionPoint к уметь указывать на функции в объектах любого типа DerivedObject или OtherDerivedObject.

Заранее спасибо

+3

Похож на [классическую проблему XY] (http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) для меня. – YSC

+0

Можете ли вы подробнее рассказать о том, что ваш прецедент? –

+0

Хорошо. У меня есть решение сейчас (ниже), но для интереса: я пишу игровой движок, используя архитектуру на основе компонентов, где компоненты общаются друг с другом с помощью простых сообщений. Сообщения состоят из таких вещей, как FORCE_X + 50, где я буду анализировать сообщение: первая половина, которая будет коррелировать с функцией, а вторая - аргументом. Я так понимаю, что она создает гибкую среду для меня, чтобы легко добавить где мне это нужно.Различные компоненты будут принимать разные сообщения и делать разные вещи. – ChrysmPsy

ответ

2

Все, что вам нужно, это static_cast заполнить карту с правильным типом.

using pfunc_type = void (ParentObject::*)() ; 
pfunc_type pfunc1 = static_cast<pfunc_type>(&DerivedObject::myFunction); 

Поскольку это допускается стандартом:

[expr.static.cast/12] - §5.2.9¶12

prvalue типа «указатель на член D типа cv1 T "может быть преобразован в prvalue типа« указатель на элемент B типа cv2 T », , где B является базовым классом (раздел [class.derived]) D, если cv2 является тем же cv- квалификация как, или gr eater cv-qualification, чем, cv1.72 Если нет действительного стандартного преобразования из «указателя на элемент B типа T» на «указатель на член D типа T» существует ([conv.mem]), программа плохо сформирован. Значение указателя нулевого элемента ([conv.mem]) преобразуется в значение указателя нулевого элемента для типа назначения. Если класс B содержит исходный элемент или является базовым или производным классом класса , содержащего исходный элемент, результирующий указатель на элемент указывает на исходный элемент. В противном случае поведение не определено. [ Примечание: хотя класс B не должен содержать исходный элемент, динамический тип объекта , с которым осуществляется косвенное обращение с помощью указателя к члену, должно содержать исходный элемент; см. [expr.mptr.oper]. - конец примечание]

Но пока это разрешено, вы должны быть очень осторожно, чтобы убедиться, что вы применить указатель элемент на объект с правильным динамическим типом.

+0

Отлично, это похоже на трюк, спасибо! – ChrysmPsy

+0

Почему поведение не определено? Почему это не может быть ошибкой компиляции? – Mikhail

+0

@Mikhail - Предположим, что функция принимает указатель на функцию-член базового класса и указатель на объект базового класса. Как бы вы проверяли во время компиляции это ограничение? – StoryTeller

 Смежные вопросы

  • Нет связанных вопросов^_^