С++ Call Pointer To Member Function

У меня есть список указателей на функции-члены, но у меня есть трудное время, пытаясь вызвать эти функции... Каков правильный синтаксис?

typedef void (Box::*HitTest) (int x, int y, int w, int h);

for (std::list<HitTest>::const_iterator i = hitTestList.begin(); i != hitTestList.end(); ++i)
{
    HitTest h = *i;
    (*h)(xPos, yPos, width, height);
}

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

std::list<HitTest> list;

for (std::list<Box*>::const_iterator i = boxList.begin(); i != boxList.end(); ++i)
{
    Box * box = *i;
    list.push_back(&box->HitTest);
}

Ответы

Ответ 1

Указатели на элементы - это уникальный зверь с уникальным синтаксисом.

У вас должен быть указатель Box, который будет использоваться как this.

(box->*h)(xPos, yPos, width, height);

Ответ 2

Вызов функции-члена через указатель на функцию-член имеет особый синтаксис:

(obj.*pmf)( params );   //  Through an object or reference.
(ptr->*pmf)( params );  //  Through a pointer.

Хотя ->* можно переопределить, оно не входит в стандартную итераторы библиотек (вероятно, потому, что для этого потребуются переопределения для каждого возможного типа функции). Так что если все, что у вас есть, это iterator, вам придется разыменовать его и использовать первую форму:

((*iter).*pmf)( params );

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

(objBox.*(*i))( params );   //  If Box is an object
(ptrBox->*(*i))( params );  //  If Box is a pointer

(Я не думаю, что вам нужны круглые скобки вокруг *i, но указатель на синтаксис членов уже достаточно особый.)

Ответ 3

Из моего "награды";-) ответ о делегатах (доступен fooobar.com/questions/44283/...):

Typedef указатель на функцию-член как это:

typedef void (T::*fn)( int anArg );

Объявите следующее:

fn functionPtr = &MyClass::MyFunction

Назовите его следующим образом:

(MyObject.*functionPtr)( argument );

Ответ 4

Ваша попытка получить указатель функции-члена через объект предает недоразумение. Указатели функции функций не включают указатель на объект, на который вы их вызываете. Вы должны указать такой указатель в точке вызова.

Как указывали многие, синтаксис для вызова функции-члена:

 obj.*funcptr(args);

или

 objptr->*funcptr(args);

В примере, который вы указали, похоже, что вам действительно нужна виртуальная функция. У вас есть стандартная операция (обнаружение, когда объект пересекается с ящиком), который должен быть вызван для многих разных типов объектов, тип которых не может быть известен во время компиляции. Это работа, которая вырезана для виртуальных функций.