Re: Different 'smart pointers'

Discussion in 'C++' started by Daniel T., Jun 8, 2004.

  1. Daniel T.

    Daniel T. Guest

    In article <c41gji$l69$>,
    "Marcin Kalicinski" <> wrote:

    >Hi all,
    >
    >I've been using a home-made kind of 'smart pointer' class for some time.
    >Recently I found out there are several smart pointer implementations in
    >boost library. But none of them actually matched what I've been doing so
    >far.
    >
    >All boost smart pointers focus on destroying the pointed object when there
    >is no more references to it. My home-made smart pointer does the reverse.
    >When some object is destroyed, values of all 'smart pointers' pointing to
    >this object change automatically to 0:
    >
    >class A { ... };
    >A *a = new A;
    >SmartPtr<A> pa = a;
    >delete a;
    >assert(pa == 0); // This assertion will succeed


    Can someone please post the smallest possible program that will cause
    the assert above to succeed?

    Given this:

    #include "SmartPtr.h"
    #include <iostream>
    using namespace std;

    class A { };

    int main() {
    A* a = new A;
    SmartPtr<A> pa = a;
    assert( pa != 0 );
    delete a;
    assert( pa == 0 );
    cout << "OK";
    }

    Show me what's inside SmartPtr.h that will make the above code print
    "OK" to cout. At the very minimum, I suspect that gobal operator delete
    has to be overridden doesn't it?
    Daniel T., Jun 8, 2004
    #1
    1. Advertising

  2. Daniel T.

    Kai-Uwe Bux Guest

    Daniel T. wrote:

    > In article <c41gji$l69$>,
    > "Marcin Kalicinski" <> wrote:
    >
    >>Hi all,
    >>
    >>I've been using a home-made kind of 'smart pointer' class for some time.
    >>Recently I found out there are several smart pointer implementations in
    >>boost library. But none of them actually matched what I've been doing so
    >>far.
    >>
    >>All boost smart pointers focus on destroying the pointed object when there
    >>is no more references to it. My home-made smart pointer does the reverse.
    >>When some object is destroyed, values of all 'smart pointers' pointing to
    >>this object change automatically to 0:
    >>
    >>class A { ... };
    >>A *a = new A;
    >>SmartPtr<A> pa = a;
    >>delete a;
    >>assert(pa == 0); // This assertion will succeed

    >
    > Can someone please post the smallest possible program that will cause
    > the assert above to succeed?
    >
    > Given this:
    >
    > #include "SmartPtr.h"
    > #include <iostream>
    > using namespace std;
    >
    > class A { };
    >
    > int main() {
    > A* a = new A;
    > SmartPtr<A> pa = a;
    > assert( pa != 0 );
    > delete a;
    > assert( pa == 0 );
    > cout << "OK";
    > }
    >
    > Show me what's inside SmartPtr.h that will make the above code print
    > "OK" to cout. At the very minimum, I suspect that gobal operator delete
    > has to be overridden doesn't it?


    Hi,

    thanks for the interesting practice problem. Just what I needed.

    I do not know how to overload delete -- I am still learning C++. However,
    here are some ideas on how your goal could be accomplished via this
    fancy overloading. This is just a rough draft, and I am sure that I
    left out many important details that one would need to address. But
    the basic functionality can be achived by keeping a multimap pairing
    memory locations and pointers to the SmartPtr<T> objects that reference
    this memory location. Upon freeing that memory location, one would
    go through the set of SmartPtr<T> objects pointing there and make them
    point to 0. Afterwords, this list will be removed from the multimap.

    Whenever a SmartPtr<T> object is reassigned a value, it will have to
    be removed and reinserted into the multimap. The implementation of this
    idea is pretty straight forward and each function is only a few lines.

    Any criticism is wellcome.

    #include <map>

    template < typename T >
    class SmartPtr {
    private:

    typedef void* Key;
    typedef SmartPtr* Data;
    typedef std::pair< const Key, Data > PairType;
    typedef std::multimap< Key, Data > LocMap;

    static LocMap loc;

    void* raw_ptr;

    void ins ( void ) {
    if ( raw_ptr != 0 ) {
    loc.insert( PairType( raw_ptr, this ) );
    }
    }

    void del ( void ) {
    if ( raw_ptr != 0 ) {
    typename LocMap::iterator iter ( loc.lower_bound( raw_ptr ) );
    while ( iter->second != this ) {
    ++ iter;
    }
    loc.erase( iter );
    raw_ptr = 0;
    }
    }

    void assign ( T* ptr ) {
    this->del();
    raw_ptr = static_cast< void* >( ptr );
    this->ins();
    }

    public:

    SmartPtr ( void ) :
    raw_ptr( 0 )
    {}

    ~SmartPtr ( void ) {
    this->del();
    }

    SmartPtr ( T* ptr ) :
    raw_ptr( 0 )
    {
    assign( ptr );
    }

    operator T* ( void ) {
    return( static_cast< T* >( raw_ptr ) );
    }

    const SmartPtr& operator= ( const SmartPtr& other ) {
    if ( this != &other ) {
    assign( other.raw_ptr );
    }
    return( *this );
    }

    static
    void remove ( T* ptr ) {
    void* raw ( static_cast< void* >( ptr ) );
    typename LocMap::iterator lower ( loc.lower_bound( raw ) );
    typename LocMap::iterator upper ( loc.upper_bound( raw ) );
    for ( typename LocMap::iterator iter ( lower );
    iter != upper;
    ++ iter ) {
    iter->second->raw_ptr = 0;
    }
    loc.erase ( lower, upper );
    }

    }; // SmartPtr<T>

    template< typename T >
    typename SmartPtr<T>::LocMap SmartPtr<T>::loc;

    #include <iostream>
    using namespace std;

    class A { };

    int main() {
    A* a = new A;
    SmartPtr<A> pa = a;
    assert( pa != 0 );
    SmartPtr<A>::remove( a ); // here I do not know how to
    delete( a ); // overload delete.
    assert( pa == 0 );
    std::cout << "OK";
    }


    Can someone please tell me, how delete can be made to do what is
    needed here?


    Best

    Kai-Uwe
    Kai-Uwe Bux, Jun 9, 2004
    #2
    1. Advertising

  3. > Given this:
    >
    > #include "SmartPtr.h"
    > #include <iostream>
    > using namespace std;
    >
    > class A { };
    >
    > int main() {
    > A* a = new A;
    > SmartPtr<A> pa = a;
    > assert( pa != 0 );
    > delete a;
    > assert( pa == 0 );
    > cout << "OK";
    > }
    >
    > Show me what's inside SmartPtr.h that will make the above code print
    > "OK" to cout. At the very minimum, I suspect that gobal operator delete
    > has to be overridden doesn't it?


    The implementation behind SmartPtr class relies on fact that only types
    derived from SmartPtrTarget can be stored in a SmartPtr. SmartPtrTarget has
    a list of all SmartPtr's that point to it, and simply clears them in its
    destructor.

    I've not investigated the idea of overloading global delete operator in
    order to accomplish the same effect.

    Best regards,
    Marcin
    Marcin Kalicinski, Jun 9, 2004
    #3
    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,308
    Howard Hinnant
    Jun 23, 2003
  2. Bonzo
    Replies:
    1
    Views:
    408
    Cy Edmunds
    Jul 23, 2003
  3. MotoK
    Replies:
    59
    Views:
    1,792
    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:
    463
    n2xssvv g02gfr12930
    Nov 27, 2005
  5. cerr

    pointers, pointers, pointers...

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

Share This Page