jorgen
jorgen

Reputation: 3593

Using function pointer from another class

I have a class containing a function pointer that will point to different functions depending on the constructor input. This works when I use the function pointer from functions within the class, but when I try to use it from an object constructed in another class I run into trouble. To illustrate here is the class header myclass.h:

using namespace std;
#include <cstdlib> 
#include <iostream>  

#ifndef MYCLASS_H
#define MYCLASS_H

class myclass{

    public: 

    void (myclass::*genericfunc)();
    void specialfunc1();
    void specialfunc2();
    void rungeneric();

    myclass(int fno) {
        if(fno==1) genericfunc=&myclass::specialfunc1;
        else if(fno==2) genericfunc=&myclass::specialfunc2;
        else {
            cerr << "ERROR: myclass must be constructed with integer input 1 or 2" << endl;
            throw std::exception();
        }
    }
};

#endif

and the class source myclass.cpp

#include "myclass.h"

void myclass::specialfunc1() {cout << "Running function 1" << endl;}

void myclass::specialfunc2() {cout << "Running function 2" << endl;}

void myclass::rungeneric() {

    (this->*genericfunc)();

}

and finally the program testmyclass.cpp:

using namespace std;
#include "myclass.h"

int main() {

    myclass classobject1(1);
    classobject1.rungeneric();

    myclass classobject2(2);
    (classobject2->*genericfunc)();

}

I compile using g++ -c myclass.cpp and g++ testmyclass.cpp myclass.o -o testmyclass. The compilation problem arises in the last line in the main function:

testmyclass.cpp: In function ‘int main()’:
testmyclass.cpp:14:18: error: ‘genericfunc’ was not declared in this scope
  (classobject2->*genericfunc)();

Upvotes: 1

Views: 906

Answers (1)

Piotr Skotnicki
Piotr Skotnicki

Reputation: 48467

In contrary to dot . and arrow ->, pointer to member operators - .* and ->* - don't serve as class member access operators, which means they do not narrow a scope in which an id-expression that follows is looked up in. You first need to access a data member holding the pointer itself:

classobject2.genericfunc

and only then apply a pointer to member operator:

(classobject2.*classobject2.genericfunc)();

which is the same as:

(classobject2.*(classobject2.genericfunc))();

The expression of form:

(this->*genericfunc)();

works, since the name genericfunc appears in the body of a member function, so it is looked up in the scope of the enclosing class.

Also, keep in mind that .* is applicable to the first operand of a class type, while ->* expects it to be a pointer to a class type:

    (&classobject2->*classobject2.genericfunc)();
//   ^ address    ^^^ arrow

Upvotes: 2

Related Questions