Reputation: 3593
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
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