Topic: overload operator-> on const-ness of method.


Author: kvilekva@nic.cerf.net (Kristian Kvilekval)
Date: 8 Jul 1994 23:50:54 GMT
Raw View

Problem:
   How to make a smart pointer to a reference counted class that
will copy the object when a method will modify it's internal data.

I was wondering how a the following scenerio might be implemented
(shortened version of an implementation).

struct T
{
   T () { refcount_ = 0; }
   unsigned refcount_;
   T *clone();

   .... /* other members */

   int NOChange () const;   //
   int Change ();
};

The problem appears when I whi to use  operator->() .
I would like a version that is applied for const methods and another
that is applied for non-const methods.  Here's my stab at the pointer
class.  Unfortunately I can't find a way to overload on the const-ness
of a method.  Any help is much appreciated.

Kris

-------------------------------------------------------------------------
Below is example of a pointer class I would like to use.

template<class T> struct Ptr
{
  Ptr() :ptr_(new T) {}
  Ptr(const Ptr<T>&p) : ptr_(p.ptr_) { ptr_->refcount_++; }
  ~Ptr()               { if (ptr_&& --ptr_->refcount_ == 0) delete ptr_; }
  operator = (const Ptr<T>&p)
  {
    delete ptr_;
    ptr_ = p.ptr_; ptr_->refcount_++;
  }
  ///////////////////////////////////////////////////
  void CopyOnWrite ()
  {
     if (ptr_&& ptr_->refcount_ > 1)
      {
        ptr_->refcount_--;
 ptr_ = ptr_->clone(); ptr_->refcount_ = 1;
      }
  }
  //
  // This operator should be used for constant methods on T.
  //
  const T* operator -> () { return ptr_ }
  //
  // This should be used for methods that change T.
  //
  T* operator -> ()
  {
      CopyOnWrite ();
      return ptr;
  }
  T *ptr_;
};

Fun()
{
  Ptr<T> P;
  Ptr<T> Q = P;
  //
  //  So far we have one copy of T allocated.
  //
  P->NOChange ();
  P->NOChange ();
  //
  // Still  have one copy of T allocated.
  //
  Q->Change ();
  //
  // P and Q now point to different object.
  //
}