C++ 类成员访问运算符->重载

  • 类成员访问运算符->重载

    类成员访问运算符(->)可以重载,但有点棘手。它被定义为使类类型具有“类似指针”的行为。运算符->必须是成员函数。如果使用,则其返回类型必须是指针或可以应用的类的对象。通常将操作符->与指针取消引用运算符*结合使用以实现“智能指针”。这些指针的行为与普通指针相同,不同之处在于它们在您通过它们访问对象时会执行其他任务,例如在指针被销毁或使用指针指向另一个对象时自动删除对象。可以将解引用运算符->定义为一元后缀运算符。也就是说,给定一个类-
    
    class Ptr {
       //...
       X * operator->();
    };
    
    可以使用类Ptr的对象以类似于使用指针的方式来访问类X的成员。例如-
    
    void f(Ptr p ) {
       p->m = 10 ; // (p.operator->())->m = 10
    }
    
    语句p->m解释为(p.operator->(())->m。使用相同的概念,以下示例说明了如何重载类访问运算符->。
    
    #include <iostream>
    #include <vector>
    using namespace std;
    
    // Consider an actual 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 above class
    class ObjContainer {
       vector<Obj*> a;
    
       public:
          void add(Obj* obj) { 
             a.push_back(obj);  // call vector's standard method.
          }
          friend class SmartPointer;
    };
    
    // implement smart pointer to access member of Obj class.
    class SmartPointer {
       ObjContainer oc;
       int index;
       
       public:
          SmartPointer(ObjContainer& objc) { 
             oc = objc;
             index = 0;
          }
       
          // Return value indicates end of list:
          bool operator++() { // Prefix version 
             if(index >= oc.a.size()) 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;
    }
    
    尝试一下
    编译并执行上述代码后,将产生以下结果-
    
    10
    12
    11
    13
    12
    14
    13
    15
    14
    16
    15
    17
    16
    18
    17
    19
    18
    20
    19
    21