I was going through this particular example of overloading ->* operator. I tried hard to get over why do we need to overload () operator but couldn't get it after a lot of googling and reerences.Eckel says that When operator ->* is called, the compiler immediately turns around and calls operator() for the return value of operator ->* . Now I know that what we want with this ->* operator is to act like a smart pointer for a class that is it should be able to reference the member functions just like a normal pointer does . So we do it like (w->* pmf)(1) and here I think that the ->* needs to know about the return value of the int in () that's why it is being overloaded on top of ->* operator. Another doubt I had in case of nested iterators that why do we need to declare the nested class before declaring it as a friend while doing overloading of -> to make it like nested iterator? I am a beginner in C++ that's why these questions may seem too naive to some sorry for that but yeah I would like a very in-depth knowledge of this stuff because I have been struggling a lot with overloading -> and ->* till now.
#include <iostream>
using namespace std;
class Dog {
public:
int run(int i) const {
cout << "run\n";
return i;
}
int eat(int i) const {
cout << "eat\n";
return i;
}
int sleep(int i) const {
cout << "ZZZ\n";
return i;
}
typedef int (Dog::*PMF)(int) const;
// operator->* must return an object
// that has an operator():
class FunctionObject {
Dog* ptr;
PMF pmem;
public:
// Save the object pointer and member pointer
FunctionObject(Dog* wp, PMF pmf): ptr(wp), pmem(pmf) {
cout << "FunctionObject constructor\n";
}
// Make the call using the object pointer
// and member pointer
int operator()(int i) const {
cout << "FunctionObject::operator()\n";
return (ptr->*pmem)(i); // Make the call
}
};
FunctionObject operator->*(PMF pmf) {
cout << "operator->*" << endl;
return FunctionObject(this, pmf);
}
};
int main() {
Dog w;
Dog::PMF pmf = &Dog::run;
cout << (w->*pmf)(1) << endl;
pmf = &Dog::sleep;
cout << (w->*pmf)(2) << endl;
pmf = &Dog::eat;
cout << (w->*pmf)(3) << endl;
}