Follow Techotopia on Twitter

On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
System/Network Admin
Programming
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Databases
Mail Systems
openSolaris
Eclipse Documentation
Techotopia.com
Virtuatopia.com
Answertopia.com

How To Guides
Virtualization
General System Admin
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Windows
Problem Solutions
Privacy Policy

  




 

 

Thinking in C++
Prev Contents / Index Next

Operator->*

The operator–>* is a binary operator that behaves like all the other binary operators. It is provided for those situations when you want to mimic the behavior provided by the built-in pointer-to-member syntax, described in the previous chapter.

Just like operator->, the pointer-to-member dereference operator is generally used with some kind of object that represents a “smart pointer,” although the example shown here will be simpler so it’s understandable. The trick when defining operator->* is that it must return an object for which the operator( ) can be called with the arguments for the member function you’re calling.

The function call operator( ) must be a member function, and it is unique in that it allows any number of arguments. It makes your object look like it’s actually a function. Although you could define several overloaded operator( ) functions with different arguments, it’s often used for types that only have a single operation, or at least an especially prominent one. You’ll see in Volume 2 that the Standard C++ Library uses the function call operator in order to create “function objects.”

To create an operator->* you must first create a class with an operator( ) that is the type of object that operator->* will return. This class must somehow capture the necessary information so that when the operator( ) is called (which happens automatically), the pointer-to-member will be dereferenced for the object. In the following example, the FunctionObject constructor captures and stores both the pointer to the object and the pointer to the member function, and then the operator( ) uses those to make the actual pointer-to-member call:

//: C12:PointerToMemberOperator.cpp
#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;
} ///:~

Dog has three member functions, all of which take an int argument and return an int. PMF is a typedef to simplify defining a pointer-to-member to Dog’s member functions.

A FunctionObject is created and returned by operator->*. Notice that operator->* knows both the object that the pointer-to-member is being called for (this) and the pointer-to-member, and it passes those to the FunctionObject constructor that stores the values. When operator->* is called, the compiler immediately turns around and calls operator( ) for the return value of operator->*, passing in the arguments that were given to operator->*. The FunctionObject::operator( ) takes the arguments and then dereferences the “real” pointer-to-member using its stored object pointer and pointer-to-member.

Notice that what you are doing here, just as with operator->, is inserting yourself in the middle of the call to operator->*. This allows you to perform some extra operations if you need to.

The operator->* mechanism implemented here only works for member functions that take an int argument and return an int. This is limiting, but if you try to create overloaded mechanisms for each different possibility, it seems like a prohibitive task. Fortunately, C++’s template mechanism (described in the last chapter of this book, and in Volume 2) is designed to handle just such a problem.

Thinking in C++
Prev Contents / Index Next

 
 
   Reproduced courtesy of Bruce Eckel, MindView, Inc. Design by Interspire