samedi 23 juillet 2016

Why the `T* operator->()` is applied repeatedly even if written once?

Why the T* operator->() is applied repeatedly even if written once? But another T& operator*() is applied once, and should be written many times.

As known there is Execute-Around Pointer Idiom in C++. More C++ Idioms/Execute-Around Pointer

Provide a smart pointer object that transparently executes actions before and after each function call on an object, given that the actions performed are the same for all functions. And before and after each treatment to member variable of a class. For example we can performs:

  • lock mutex
  • log action
  • visualize changing data

I added some in main() to this example:

#include <iostream>
#include <vector>

class VisualizableVector {
  public:
    class proxy {
      public:
        proxy (std::vector<int> *v) : vect (v) {
            std::cout << "Before size is: " << vect->size() << std::endl;
        }
        std::vector<int> * operator -> () { return vect; }
        std::vector<int> & operator * () { return *vect; }
        ~proxy () { std::cout << "After size is: " << vect->size() << std::endl; }
      private:
        std::vector <int> * vect;
    };

    VisualizableVector (std::vector<int> *v) : vect(v) {}            
    proxy operator -> () { return proxy (vect); }
    proxy operator * () { return proxy (vect); }
  private:
    std::vector <int> * vect;
};

int main()
{
  VisualizableVector vecc (new std::vector<int>);

  vecc->push_back (10);         // 1. Note use of -> operator instead of . operator      
  vecc->push_back (20);         // 2. ok      
  (*vecc)->push_back (30);      // 3. ok      
  // (*vecc).push_back (40);    // 4. error      
  (**vecc).push_back (50);      // 5. ok      
  // vecc->->push_back (60);    // 6. error     
}

Online compiler result: http://ift.tt/2a3WrFv

Why do we need to write twice **, but only once -> ?

Its operator return the same thing proxy:

    proxy operator -> () { return proxy (vect); }
    proxy operator * () { return proxy (vect); }

But why do we need to use * again, but we shouldn't use -> again?:

  vecc->push_back (20);     // 2. ok      (vecc->) is proxy
  (**vecc).push_back (50);  // 5. ok      (*vecc) is proxy

Why not vecc->->push_back (20);?

Is there anything about this in the standard C++ (03/11/14)?

Aucun commentaire:

Enregistrer un commentaire