smart pointers

Discussion in 'C++' started by keith@bytebrothers.co.uk, Feb 14, 2008.

  1. Guest

    When I am using the private implementation idiom, is there anything to
    be gained by using a boost::scoped_ptr as opposed to a auto_ptr? I
    confess I'm not that clear on the differences...
    , Feb 14, 2008
    #1
    1. Advertising

  2. Cholo Lennon Guest

    On Feb 14, 10:27 am, wrote:
    > When I am using the private implementation idiom, is there anything to
    > be gained by using a boost::scoped_ptr as opposed to a auto_ptr? I
    > confess I'm not that clear on the differences...


    If your classes are noncopyable: a const auto_ptr to hold the pimpl is
    almost the same than scoped_ptr: scoped_ptr can be 'reset' to change
    the pointee pimpl. You can't change the pointee pimpl with const
    auto_ptr

    If your classes are copyable: auto_ptr can't be const and non const
    auto_ptr leads you to the disaster due to auto_ptr's transfer
    ownership. When my classes are copyable I prefer using shared_ptr to
    hold the pimpl (to avoid the manual coding of pimpl copy)

    Regards

    --
    Cholo Lennon
    Bs.As.
    ARG
    Cholo Lennon, Feb 14, 2008
    #2
    1. Advertising

  3. Guest

    On 14 Feb, 13:57, Cholo Lennon <> wrote:
    > On Feb 14, 10:27 am, wrote:
    >
    > > When I am using the private implementation idiom, is there anything to
    > > be gained by using a boost::scoped_ptr as opposed to a auto_ptr? I
    > > confess I'm not that clear on the differences...

    >
    > If your classes are noncopyable: a const auto_ptr to hold the pimpl is
    > almost the same than scoped_ptr: scoped_ptr can be 'reset' to change
    > the pointee pimpl. You can't change the pointee pimpl with const
    > auto_ptr
    >
    > If your classes are copyable: auto_ptr can't be const and non const
    > auto_ptr leads you to the disaster due to auto_ptr's transfer
    > ownership. When my classes are copyable I prefer using shared_ptr to
    > hold the pimpl (to avoid the manual coding of pimpl copy)


    I'm unclear exactly what non-copyable means in this context. The
    following seems to copy just fine.

    Here's part of a wrapper class for an MD5 hash I've been playing with
    to get to grips with this pimpl stuff:

    //-----------------------------------
    #include <boost/scoped_ptr.hpp>
    #include <stdint.h>
    #include "hash.h"

    class MD5Private;
    class MD5 : public virtual Hash
    {
    public:
    using Hash::hash;
    using Hash::end;
    using Hash::digest;

    MD5();
    MD5(const MD5& h);
    MD5& operator= (const MD5& h) throw();
    virtual ~MD5() throw();

    virtual void begin () throw();
    virtual void hash (const uint8_t* data, const uint_32t& len)
    throw();
    virtual void end (const uint8_t* hval) throw();

    private:
    boost::scoped_ptr<MD5Private> p_;
    };
    //--------------------------

    and in the relevant bits of the class definition I currently have:

    //--------------------------
    class MD5Private {
    public:
    uint32_t i[2];
    uint32_t buf[4];
    uint8_t in[64];
    uint8_t digest[16];
    };

    // New object, so initialise
    MD5::MD5() : p_(new MD5Private()) { begin(); }

    // Copy object, so do _not_ initialise
    MD5::MD5(const MD5& other) :
    Hash(other),
    p_(other.p_.get() ? new MD5Private(*other.p_) : NULL)
    { }

    MD5::~MD5() throw() { }

    MD5&
    MD5::eek:perator= (const MD5& rhs) throw()
    {
    MD5 temp(rhs);
    swap(p_, temp.p_);
    return *this;
    }
    //<etc, etc>
    //--------------------------

    Are you saying that by using a boost::scoped_ptr this should not work?
    , Feb 14, 2008
    #3
  4. Cholo Lennon Guest

    On Feb 14, 1:35 pm, wrote:
    > On 14 Feb, 13:57, Cholo Lennon <> wrote:
    >
    > > On Feb 14, 10:27 am, wrote:

    >
    > > > When I am using the private implementation idiom, is there anything to
    > > > be gained by using a boost::scoped_ptr as opposed to a auto_ptr? I
    > > > confess I'm not that clear on the differences...

    >
    > > If your classes are noncopyable: a const auto_ptr to hold the pimpl is
    > > almost the same than scoped_ptr: scoped_ptr can be 'reset' to change
    > > the pointee pimpl. You can't change the pointee pimpl with const
    > > auto_ptr

    >
    > > If your classes are copyable: auto_ptr can't be const and non const
    > > auto_ptr leads you to the disaster due to auto_ptr's transfer
    > > ownership. When my classes are copyable I prefer using shared_ptr to
    > > hold the pimpl (to avoid the manual coding of pimpl copy)

    >
    > I'm unclear exactly what non-copyable means in this context. The
    > following seems to copy just fine.
    >
    > Here's part of a wrapper class for an MD5 hash I've been playing with
    > to get to grips with this pimpl stuff:
    >
    > //-----------------------------------
    > #include <boost/scoped_ptr.hpp>
    > #include <stdint.h>
    > #include "hash.h"
    >
    > class MD5Private;
    > class MD5 : public virtual Hash
    > {
    > public:
    > using Hash::hash;
    > using Hash::end;
    > using Hash::digest;
    >
    > MD5();
    > MD5(const MD5& h);
    > MD5& operator= (const MD5& h) throw();
    > virtual ~MD5() throw();
    >
    > virtual void begin () throw();
    > virtual void hash (const uint8_t* data, const uint_32t& len)
    > throw();
    > virtual void end (const uint8_t* hval) throw();
    >
    > private:
    > boost::scoped_ptr<MD5Private> p_;};
    >
    > //--------------------------
    >
    > and in the relevant bits of the class definition I currently have:
    >
    > //--------------------------
    > class MD5Private {
    > public:
    > uint32_t i[2];
    > uint32_t buf[4];
    > uint8_t in[64];
    > uint8_t digest[16];
    >
    > };
    >
    > // New object, so initialise
    > MD5::MD5() : p_(new MD5Private()) { begin(); }
    >
    > // Copy object, so do _not_ initialise
    > MD5::MD5(const MD5& other) :
    > Hash(other),
    > p_(other.p_.get() ? new MD5Private(*other.p_) : NULL)
    > { }
    >
    > MD5::~MD5() throw() { }
    >
    > MD5&
    > MD5::eek:perator= (const MD5& rhs) throw()
    > {
    > MD5 temp(rhs);
    > swap(p_, temp.p_);
    > return *this;}
    >
    > //<etc, etc>
    > //--------------------------
    >
    > Are you saying that by using a boost::scoped_ptr this should not work?


    No, I'm saying that using scoped_ptr you have to define copy ctor and
    operator= like you did. Your code seems to be perfectly valid.

    and... I'm sorry, I did a mistake when I said:

    "When my classes are copyable I prefer using shared_ptr to
    hold the pimpl (to avoid the manual coding of pimpl copy)"

    It should have been:

    "When my classes are copyable and the internals details have to be
    shared I use shared_ptr (with shared_ptr you don't have to define copy
    ctor and operator="

    (It's very common for me to use classes with internal shared details,
    this was the source of my mistake).


    BTW, I prefer using a nested private class for pimpl data:

    class MD5 {

    private:
    class Private;
    boost::scoped_ptr<Private> p_;
    };

    ....

    class MD5::private { ... };



    Regards


    --
    Cholo Lennon
    Bs.As.
    ARG
    Cholo Lennon, Feb 14, 2008
    #4
  5. Guest

    On 14 Feb, 16:00, Cholo Lennon <> wrote:
    > On Feb 14, 1:35 pm, wrote:
    >
    > > Are you saying that by using a boost::scoped_ptr this should not work?

    >
    > No, I'm saying that using scoped_ptr you have to define copy ctor and
    > operator= like you did. Your code seems to be perfectly valid.


    Thanks. I think I've got it now.

    > BTW, I prefer using a nested private class for pimpl data:
    >
    > class MD5 {
    >
    > private:
    > class Private;
    > boost::scoped_ptr<Private> p_;
    >
    > };
    >
    > ...
    >
    > class MD5::private { ... };


    That's neater - I like it. Thanks again.
    , Feb 15, 2008
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Evan
    Replies:
    1
    Views:
    1,307
    Howard Hinnant
    Jun 23, 2003
  2. Bonzo
    Replies:
    1
    Views:
    407
    Cy Edmunds
    Jul 23, 2003
  3. MotoK
    Replies:
    59
    Views:
    1,785
    Keith Thompson
    Sep 15, 2006
  4. n2xssvv g02gfr12930

    Smart pointers and member function pointers

    n2xssvv g02gfr12930, Nov 26, 2005, in forum: C++
    Replies:
    3
    Views:
    461
    n2xssvv g02gfr12930
    Nov 27, 2005
  5. cerr

    pointers, pointers, pointers...

    cerr, Apr 7, 2011, in forum: C Programming
    Replies:
    12
    Views:
    652
Loading...

Share This Page