title: Reference Counting in C++ OO-Style
body: <p>I came accross an intriguing implementation of a base class on the <a href="http://www.parashift.com/c++-faq/ref-count-with-cow-hierarchy.html" rel="noreferrer">C++ FAQ</a> that, according to my naive understanding, could serve as an alternative to some of the smart pointer implementations (e.g. shared_ptr).  Here's the example code verbatim, but please follow the link above for an explanation:</p>
  
  <pre><code>class Fred {
  public:
  
    static Fred create1(std::string const&amp; s, int i);
    static Fred create2(float x, float y);
  
    Fred(Fred const&amp; f);
    Fred&amp; operator= (Fred const&amp; f);
   ~Fred();
  
    void sampleInspectorMethod() const;   // No changes to this object
    void sampleMutatorMethod();           // Change this object
  
    ...
  
  private:
  
    class Data {
    public:
      Data() : count_(1) { }
      Data(Data const&amp; d) : count_(1) { }              // Do NOT copy the 'count_' member!
      Data&amp; operator= (Data const&amp;) { return *this; }  // Do NOT copy the 'count_' member!
      virtual ~Data() { assert(count_ == 0); }         // A virtual destructor
      virtual Data* clone() const = 0;                 // A virtual constructor
      virtual void sampleInspectorMethod() const = 0;  // A pure virtual function
      virtual void sampleMutatorMethod() = 0;
    private:
      unsigned count_;   // count_ doesn't need to be protected
      friend class Fred; // Allow Fred to access count_
    };
  
    class Der1 : public Data {
    public:
      Der1(std::string const&amp; s, int i);
      virtual void sampleInspectorMethod() const;
      virtual void sampleMutatorMethod();
      virtual Data* clone() const;
      ...
    };
  
    class Der2 : public Data {
    public:
      Der2(float x, float y);
      virtual void sampleInspectorMethod() const;
      virtual void sampleMutatorMethod();
      virtual Data* clone() const;
      ...
    };
  
    Fred(Data* data);
    // Creates a Fred smart-reference that owns *data
    // It is private to force users to use a createXXX() method
    // Requirement: data must not be NULL
  
    Data* data_;   // Invariant: data_ is never NULL
  };
  
  Fred::Fred(Data* data) : data_(data)  { assert(data != NULL); }
  
  Fred Fred::create1(std::string const&amp; s, int i) { return Fred(new Der1(s, i)); }
  Fred Fred::create2(float x, float y)            { return Fred(new Der2(x, y)); }
  
  Fred::Data* Fred::Der1::clone() const { return new Der1(*this); }
  Fred::Data* Fred::Der2::clone() const { return new Der2(*this); }
  
  Fred::Fred(Fred const&amp; f)
    : data_(f.data_)
  {
    ++data_-&gt;count_;
  }
  
  Fred&amp; Fred::operator= (Fred const&amp; f)
  {
    // DO NOT CHANGE THE ORDER OF THESE STATEMENTS!
    // (This order properly handles self-assignment)
    // (This order also properly handles recursion, e.g., if a Fred::Data contains Freds)
    Data* const old = data_;
    data_ = f.data_;
    ++data_-&gt;count_;
    if (--old-&gt;count_ == 0) delete old;
    return *this;
  }
  
  Fred::~Fred()
  {
    if (--data_-&gt;count_ == 0) delete data_;
  }
  
  void Fred::sampleInspectorMethod() const
  {
    // This method promises ("const") not to change anything in *data_
    // Therefore we simply "pass the method through" to *data_:
    data_-&gt;sampleInspectorMethod();
  }
  
  void Fred::sampleMutatorMethod()
  {
    // This method might need to change things in *data_
    // Thus it first checks if this is the only pointer to *data_
    if (data_-&gt;count_ &gt; 1) {
      Data* d = data_-&gt;clone();   // The Virtual Constructor Idiom
      --data_-&gt;count_;
      data_ = d;
    }
    assert(data_-&gt;count_ == 1);
  
    // Now we "pass the method through" to *data_:
    data_-&gt;sampleMutatorMethod();
  }
  </code></pre>
  
  <p>I don't see this approach being used in any C++ libraries; although it seems quite elegant.  Assuming a single-threaded environment, for the sake of simplicity, please answer the following questions:</p>
  
  <ol>
  <li>Is this a suitable alternative to the smart pointer approach for managing the lifetime of objects, or is it just asking for trouble?</li>
  <li>If it is suitable, why do you suppose it's not used more often?</li>
  </ol>