Boost logo

Boost :

From: Kevin Atkinson (kevinatk_at_[hidden])
Date: 2000-03-06 00:55:26


I want two propose two pseudo smart points which I have found extremely
useful in my code.

CopyPtr ptr primary used to avoid unnecessary interdependencies and to
support the pimpl idiom. A typical usage would be:

class Foo {
  class Pimpl;
  CopyPtr<Pimpl> pimpl_;
};

or

class Bar;
class Foo {
  CopyPtr<Bar> bar_;
};

As is usage when ever one CopyPtr gets assigned to another a copy is
made.

ClonePtr is like CopyPtr except it is used when the exact type of the
object is not known at compile time. The class is excepted to have the
a clone() meted which will create a new copy of the object alloacted
with new and the assign(const ClassName *) which will assign one object
to another. Its usage is basically the same.

Of the I find ClonePtr far more useful as it it can be used with
abstract base classes.

With the STL, and these two pseudo smart pointers I find that I hardy
ever have to worry amount memory management in my code.

For example of these two classes in use see my Aspell program
(http://aspell.sourceforge.net/).

Naturally the namespace and perhaps the naming should be changed before
final inclusion in the boost project.

-- 
Kevin Atkinson
kevinatk_at_[hidden]
http://metalab.unc.edu/kevina/

// Copyright (c) 2000
// Kevin Atkinson
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without
// fee, provided that the above copyright notice appear in all copies
// and that both that copyright notice and this permission notice
// appear in supporting documentation. Kevin Atkinson makes no
// representations about the suitability of this software for any
// purpose. It is provided "as is" without express or implied
// warranty.

#ifndef __autil_copy_ptr__
#define __autil_copy_ptr__

namespace autil {

  template <typename Class>
  class CopyPtr {
  public:
    Class * ptr;
    bool own;
    CopyPtr() : ptr(0), own(true) {}
    CopyPtr(Class * p, bool o = true) : ptr(p), own(o) {}
    CopyPtr(const CopyPtr & other);
    CopyPtr & operator= (const CopyPtr & other);
    Class & operator* () const {return *ptr;}
    Class * operator-> () const {return ptr;}
    operator Class * () const {return ptr;}
    CopyPtr & operator=(Class * p) {ptr = p; return *this;}
    operator bool () const {return ptr;}
    ~CopyPtr();
  };

}

#endif


// Copyright (c) 2000
// Kevin Atkinson
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without
// fee, provided that the above copyright notice appear in all copies
// and that both that copyright notice and this permission notice
// appear in supporting documentation. Kevin Atkinson makes no
// representations about the suitability of this software for any
// purpose. It is provided "as is" without express or implied
// warranty.

#ifndef _autil_copy_ptr__
#define _autil_copy_ptr__

#include "copy_ptr.hh"

namespace autil {

  template <typename Class>
  CopyPtr<Class>::CopyPtr(const CopyPtr<Class> &other) {
    if (other.own)
      ptr = new Class(*other.ptr);
    else
      ptr = other.ptr;
    own = other.own;
  }

  template <typename Class>
  CopyPtr<Class> &
  CopyPtr<Class>::operator= (const CopyPtr<Class> & other)
  {
    if (own) delete ptr;
    if (other.own)
      ptr = new Class(*other.ptr);
    else
      ptr = other.ptr;
    own = other.own;
    return *this;
  }

  template <typename Class>
  CopyPtr<Class>::~CopyPtr() {
    if (own) delete ptr;
  }

}

#endif


// Copyright (c) 2000
// Kevin Atkinson
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without
// fee, provided that the above copyright notice appear in all copies
// and that both that copyright notice and this permission notice
// appear in supporting documentation. Kevin Atkinson makes no
// representations about the suitability of this software for any
// purpose. It is provided "as is" without express or implied
// warranty.

#ifndef __autil_clone_ptr__
#define __autil_clone_ptr__

// The copy constructor calls clone to create a new copy

// The assignment operator calls the copy method of the current ptr
// unless it is null. If null it will clone the other object.

namespace autil {

  template <typename Class>
  class ClonePtr {
  public:
    Class * ptr;

    ClonePtr() : ptr(0) {}
    explicit ClonePtr(Class * p) : ptr(p) {}
    
    ClonePtr(const ClonePtr & other);
    ClonePtr & operator= (Class * p);
    ClonePtr & operator= (const ClonePtr & other) {
      assign(other.ptr);
      return *this;
    }
    
    void assign(const Class * p);

    operator Class * () const {return ptr;}
    Class & operator * ()const {return *ptr;}
    Class * operator-> () const {return ptr;}
    operator bool () const {return ptr;}

    void del();
    
    ~ClonePtr();
  };

}

#endif


// Copyright (c) 2000
// Kevin Atkinson
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without
// fee, provided that the above copyright notice appear in all copies
// and that both that copyright notice and this permission notice
// appear in supporting documentation. Kevin Atkinson makes no
// representations about the suitability of this software for any
// purpose. It is provided "as is" without express or implied
// warranty.

#ifndef __autil_clone_ptr_t__
#define __autil_clone_ptr_t__

#include <typeinfo>
#include "clone_ptr.hh"

namespace autil {

  template <typename Class>
  ClonePtr<Class>::ClonePtr(const ClonePtr<Class> &other) {
    if (other.ptr) ptr = other.ptr->clone();
    else ptr = 0;
  }

  template <typename Class>
  inline void clone_ptr_assign_same_id(ClonePtr<Class> & ths,
                                       const Class * other_ptr)
  {
    ths.ptr->assign(other_ptr);
  }

  template <typename Class>
  inline void clone_ptr_assign_same_id(ClonePtr<const Class> & ths,
                                       const Class * other_ptr)
  {
    delete ths.ptr;
    ths.ptr = other_ptr->clone();
  }

  template <typename Class>
  void ClonePtr<Class>::assign(const Class * other_ptr)
  {
    if (ptr) {
      if (other_ptr) {
        if (typeid(*ptr) == typeid(*other_ptr)) {
          clone_ptr_assign_same_id(*this, other_ptr);
        } else {
          delete ptr;
          ptr = other_ptr->clone();
        }
      } else {
        delete ptr;
        ptr = 0;
      }
    } else {
      if (other_ptr) ptr = other_ptr->clone();
      else ptr = 0;
    }
  }
  
  template <typename Class>
  ClonePtr<Class> &
  ClonePtr<Class>::operator= (Class * other) {
    delete ptr;
    ptr = other;
    return *this;
  }

  template <typename Class>
  void ClonePtr<Class>::del() {
    delete ptr;
    ptr = 0;
  }
  
  template <typename Class>
  ClonePtr<Class>::~ClonePtr() {
    delete ptr;
  }
  
}

#endif


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk