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

// 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

Няма променлива, наречена fPtr в обхвата на функцията main(). Трябва да се обърнете към членската променлива с помощта на оператор -> и след това да дереферирате указател към член с помощта на ->*:

// 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