Easy Tutorial
❮ Cpp Constants Literals Cpp Multithreading ❯

C++ Class Member Access Operator -> Overloading

C++ Overloading Operators and Overloaded Functions

The class member access operator (->) can be overloaded, but it is more complex. It is defined to give a class "pointer-like" behavior. The operator -> must be a member function. If used, the return type must be a pointer or an object of the class.

The operator -> is commonly used in conjunction with the dereference operator * to implement "smart pointers". These pointers are objects that behave like regular pointers, except they perform additional tasks, such as automatically deleting objects when the pointer is destroyed or when the pointer points to another object.

The dereference operator -> can be defined as a unary postfix operator. That is, given a class:

class Ptr {
   //...
   X* operator->();
};

Objects of class Ptr can be used to access members of class X in a way similar to using pointers. For example:

void f(Ptr p)
{
   p->m = 10; // (p.operator->())->m = 10
}

The statement p->m is interpreted as (p.operator->())->m. Similarly, the following example demonstrates how to overload the class member access operator ->.

Example

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

// Assume a real class
class Obj {
   static int i, j;
public:
   void f() const { cout << i++ << endl; }
   void g() const { cout << j++ << endl; }
};

// Static member definitions
int Obj::i = 10;
int Obj::j = 12;

// Implement a container for the class above
class ObjContainer {
   vector<Obj*> a;
public:
   void add(Obj* obj)
   { 
      a.push_back(obj);  // Call the standard method of the vector
   }
   friend class SmartPointer;
};

// Implement a smart pointer to access members of class Obj
class SmartPointer {
   ObjContainer oc;
   int index;
public:
   SmartPointer(ObjContainer& objc)
   { 
       oc = objc;
       index = 0;
   }
   // Return value indicates the end of the list
   bool operator++() // Prefix version
   { 
     if(index >= oc.a.size() - 1) return false;
     if(oc.a[++index] == 0) return false;
     return true;
   }
   bool operator++(int) // Postfix version
   { 
      return operator++();
   }
   // Overload operator ->
   Obj* operator->() const 
   {
     if(!oc.a[index])
     {
        cout << "Zero value";
        return (Obj*)0;
     }
     return oc.a[index];
   }
};

int main() {
   const int sz = 10;
   Obj o[sz];
   ObjContainer oc;
   for(int i = 0; i < sz; i++)
   {
       oc.add(&o[i]);
   }
   SmartPointer sp(oc); // Create an iterator
   do {
      sp->f(); // Smart pointer call
      sp->g();
   } while(sp++);
   return 0;
}

When the above code is compiled and executed, it produces the following result:

10
12
11
13
12
14
13
15
14
16
15
17
16
18
17
19
18
20
19
21

C++ Overloading Operators and Overloaded Functions

❮ Cpp Constants Literals Cpp Multithreading ❯