Boost logo

Boost :

From: Nicolai Josuttis (nicolai.josuttis_at_[hidden])
Date: 2000-03-07 13:40:35


For a customer I verified the smart pointer stuff.
I have several comments and (at the end) some design
issues:

- documentation bugs:
    smart_ptr/scoped_ptr.htm, 3rd paragraph:
        replace: See scoped_array for that usage.
        by: ... scoped_ptr ...
        (including an update of the link)
    smart_ptr/shared_array.htm, 3rd paragraph:
        replace: See shared_array for that usage.
        by: ... shared_ptr ...
        although the link is correct
    smart_ptr/scoped_ptr.htm
        the link to noncopyable in the synopsis is somehow broken
    smart_ptr/smarttests.htm:
        I don't see the description mebntioned here:
            "iv. Linked pointer as described above - linked."
    smart_ptr/scoped_ptr.htm:
        "void main()" is not standard conform and has to get changed
        into: "int main()"

- documentation enhancements:
    all smart pointer documentations:
        a link back to the top page smart_ptr/smart_ptr.htm
         should be there (people might start there for whatever reason)
    smart_ptr/smart_ptr.htm:
        I'd like to see mor rationals for how these shared pointers
         supplement auto_ptr or for which purpose they are.
        Something like:
         scoped_ptr is a restricted auto_ptr in that it doesn't allow
         transfer of ownership.
    in all for synopsis it would be great to let
        #include <boost/smart_ptr.hpp> refer to the original source file.
         
- smart_ptr.hpp:
        a few lines end with ^M

Questions:

o Shouldn't auto_array be provided (for completeness) ?

o The decision was made to use a direct detached implementation
  technique. To cite the text:
   "We went so far as to run various timings of the direct and indirect
approaches, and found
    that at least on Intel Pentium chips there was very little measurable
difference."
  However, the smart pointer tests give a totally different view. Following them
  using a direct detached implementation is a significant penalty.
  So, why do we still use the direct detached implementation technique?

o I wonder, whether it would be useful to parametrize the release operation,
  at least for scoped_ptr and scoped_array.
  Couldn't we implement a template for two types, the element type and the
  release operation. This would allow to use the "resource acquisition is
  initialization" idiom with other acquisitions than new and new[].
  Attached is an example implementation.

Best
 Nico

-- 
Nicolai M. Josuttis          	http://www.josuttis.de/
Solutions in Time        	mailto:solutions_at_[hidden]

// class noncopyable -------------------------------------------------------//

// Private copy constructor and copy assignment ensure classes derived from
// class noncopyable cannot be copied.

// Contributed by Dave Abrahams

class noncopyable
{
    protected:
        noncopyable(){}
        ~noncopyable(){}
    private: // emphasize the following members are private
        noncopyable( const noncopyable& );
        const noncopyable& operator=( const noncopyable& );
}; // noncopyable

template<typename T, typename OP>
class scoped_resource : noncopyable {

  T* ptr;

 public:
  typedef T element_type;

  explicit scoped_resource( T* p=0 ) throw() : ptr(p) {}
  ~scoped_resource() { OP()(ptr); }

  void reset( T* p=0 ) { if ( ptr != p ) { OP()(ptr); ptr = p; } }
  T& operator*() const throw() { return *ptr; }
  T* operator->() const throw() { return ptr; }
  T* get() const throw() { return ptr; }
#ifdef BOOST_SMART_PTR_CONVERSION
  // get() is safer! Define BOOST_SMART_PTR_CONVERSION at your own risk!
  operator T*() const throw() { return ptr; }
#endif
}; // scoped_resource

template <typename T>
class FO_delete_ptr {
  public:
    void operator() (T* p) {
        delete p;
    }
};

template <typename T>
class FO_delete_array {
  public:
    void operator() (T* p) {
        delete [] p;
    }
};

#include <iostream>

struct Shoe { ~Shoe(){ std::cout << "Buckle my shoe" << std::endl; } };

class MyClass {
    scoped_resource<int,FO_delete_ptr<int> > ptr;
  public:
    MyClass() : ptr(new int) { *ptr = 0; }
    int add_one() { return ++*ptr; }
};

int main() {
    MyClass my_instance;
    std::cout << my_instance.add_one() << std::endl;
    std::cout << my_instance.add_one() << std::endl;

    scoped_resource<Shoe,FO_delete_ptr<Shoe> > x(new Shoe);

    scoped_resource<Shoe,FO_delete_array<Shoe> > y(new Shoe[5]);
}


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