Указатель функции члена класса как член класса

// class
class MyClass
{
public:
void doIt() const
{
    cout << "It works!" << endl;
}

void(MyClass::*fPtr)() const;
};

// main

MyClass *t = new MyClass;

// store function address
t->fPtr = &MyClass::doIt;

(*(t->fPtr))(); // Whats wrong with this line?

Как я могу вызвать функцию, хранящуюся в fPtr? когда я пытаюсь (*(t->fPtr))(); компилятор выдает эти ошибки:

ошибка C2171: '*': недопустимо для операндов типа 'void (__thiscall MyClass::*) (void) const

ошибка C2064: термин не оценивается как функция, принимающая 0 аргументов


person Suicidal    schedule 21.12.2011    source источник
comment
(t->*(t->fPtr))() думаю должно сработать   -  person KoKuToru    schedule 21.12.2011
comment
@KoKuToru: Это тоже неправильно.   -  person Nawaz    schedule 21.12.2011
comment
@KoKuToru: Не могли бы вы опубликовать свой комментарий в качестве ответа?   -  person ruakh    schedule 21.12.2011


Ответы (2)


(*(t->fPtr))(); неверен, правильный синтаксис ((object)->*(ptrToMember))

означает

(t->*(t->fPtr))();

Дополнительная справочная информация здесь: http://www.parashift.com/c++-faq-lite/pointers-to-members.html (но лучше игнорировать эти макросы с этой страницы..)

person KoKuToru    schedule 21.12.2011

В области действия функции main() нет переменной с именем fPtr. Вам нужно сослаться на переменную-член, используя оператор ->, а затем разыменовать указатель на член, используя ->*:

// main

MyClass *t = new MyClass;

// store function adress
t->fPtr = &MyClass::doIt;   

(t->*(t->fPtr))();

В качестве альтернативы вы можете создать локальную переменную и присвоить ей указатель на член:

// main

MyClass *t = new MyClass;

// store function adress
t->fPtr = &MyClass::doIt;

void (MyClass::*fp)() const = t->fPtr;
(t->*fp)();

Последнее проясняет, зачем нужна странная на вид конструкция выше. Вы также можете выполнить метод для объекта, отличного от того, чью переменную-член типа указатель на член вы используете:

MyClass *s = new MyClass;
MyClass *t = new MyClass;

s->fPtr = &MyClass::f;
t->fPtr = &MyClass::g;

(t->*(s->fPtr))(); // Call f() on object *t
(s->*(t->fPtr))(); // Call g() on object *s

Объект слева от -> сообщает компилятору, из какого объекта следует считать указатель на член, а объект слева от ->* сообщает компилятору, для какого объекта вызывать функцию-член.

person Adam Zalcman    schedule 21.12.2011