Threaded SmartPtr questions

Discussion in 'C++' started by dbtouch, May 6, 2009.

  1. dbtouch

    dbtouch Guest

    Dear C++ Users,

    I am studying Modern C++ design and I simplified a threaded smart
    pointer implementation as following code. As I execute it I found that
    tsp is actually deleted twice. I am trying to see whether my approach
    is correct and would like to hear your opinions.

    dbtouch

    #include <iostream>

    class Foo {
    public:
    void func() {
    std::cout << "Foo::func()" << std::endl;
    }

    Foo(const Foo& f) {
    std::cout << "Foo::Foo(const Foo&)" << std::endl;
    }

    Foo() {
    std::cout << "Foo::Foo()" << std::endl;
    }

    ~Foo() {
    std::cout << "Foo:~Foo()" << std::endl;
    }
    };

    class Mutex {
    public:
    void acquire() {
    std::cout << "Mutex.acquire()" << std::endl;
    }
    void release() {
    std::cout << "Mutex.release()" << std::endl;
    }
    };

    template <typename SharedObject, typename SyncPolicy>
    class ThreadedSmartPtr {
    SharedObject* m_ptr;
    Mutex lock;

    public:
    ThreadedSmartPtr(SharedObject* ptr, SyncPolicy& lck) :
    m_ptr(ptr), lock(lck) {
    lock.acquire();
    }

    ~ThreadedSmartPtr() {
    lock.release();
    }

    SharedObject* operator -> () {
    return m_ptr;
    }
    };

    template <typename T>
    class SmartPtr {
    T *object;

    public:
    SmartPtr(T* value) : object(value) {
    }

    T operator->() {
    return *object;
    }

    ~SmartPtr() {
    if (object)
    delete object;
    }
    };

    typedef ThreadedSmartPtr<Foo, Mutex> oldSmartPtr;

    int main() {
    Foo *ptr = new Foo;
    Mutex m;
    oldSmartPtr tsp(ptr, m);

    SmartPtr<oldSmartPtr> sp(&tsp);
    sp->func();
    }
     
    dbtouch, May 6, 2009
    #1
    1. Advertising

  2. dbtouch

    James Kanze Guest

    On May 6, 11:44 pm, dbtouch <> wrote:

    > I am studying Modern C++ design


    I'm not sure of your level, but from what I've seen and heard of
    it, I don't think it's exactly for beginners in C++.

    > and I simplified a threaded
    > smart pointer implementation as following code. As I execute
    > it I found that tsp is actually deleted twice. I am trying to
    > see whether my approach is correct and would like to hear your
    > opinions.


    There are at least two serious problems with your code.

    > #include <iostream>


    > class Foo {
    > public:
    > void func() {
    > std::cout << "Foo::func()" << std::endl;
    > }


    > Foo(const Foo& f) {
    > std::cout << "Foo::Foo(const Foo&)" << std::endl;
    > }


    > Foo() {
    > std::cout << "Foo::Foo()" << std::endl;
    > }


    > ~Foo() {
    > std::cout << "Foo:~Foo()" << std::endl;
    > }
    > };


    > class Mutex {


    Not important in your example, but a real Mutex will have
    identity. Which means that it won't support copy nor
    assignment. Whatever you end up designing, you must take this
    into account.

    > public:
    > void acquire() {
    > std::cout << "Mutex.acquire()" << std::endl;
    > }
    > void release() {
    > std::cout << "Mutex.release()" << std::endl;
    > }
    > };


    > template <typename SharedObject, typename SyncPolicy>
    > class ThreadedSmartPtr {
    > SharedObject* m_ptr;
    > Mutex lock;


    If Mutex isn't copiable, nor is your ThreadedSmartPtr. (That
    may or may not be a problem. The smart pointers I've seen which
    manage locks all use reference counting to support copy.)

    And of course, since the mutex is only known to the single
    instance, there's no way it can protect anything not using the
    particular instance.

    > public:
    > ThreadedSmartPtr(SharedObject* ptr, SyncPolicy& lck) :
    > m_ptr(ptr), lock(lck) {
    > lock.acquire();
    > }


    > ~ThreadedSmartPtr() {
    > lock.release();
    > }


    > SharedObject* operator -> () {
    > return m_ptr;
    > }
    > };


    > template <typename T>
    > class SmartPtr {
    > T *object;


    > public:
    > SmartPtr(T* value) : object(value) {
    > }


    > T operator->() {
    > return *object;
    > }


    > ~SmartPtr() {
    > if (object)
    > delete object;
    > }
    > };


    > typedef ThreadedSmartPtr<Foo, Mutex> oldSmartPtr;


    > int main() {
    > Foo *ptr = new Foo;
    > Mutex m;
    > oldSmartPtr tsp(ptr, m);


    > SmartPtr<oldSmartPtr> sp(&tsp);


    And this will result in undefined behavior. As written, your
    SmartPtr can only be initialized with dynamically allocated
    objects.

    > sp->func();


    > }


    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, May 7, 2009
    #2
    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. Weston Weems

    More Threaded Cache Loading questions...

    Weston Weems, Jan 5, 2005, in forum: ASP .Net
    Replies:
    4
    Views:
    438
    Kevin Spencer
    Jan 5, 2005
  2. Replies:
    1
    Views:
    343
    mlimber
    Dec 30, 2005
  3. mosfet

    SmartPtr Issues

    mosfet, Aug 12, 2008, in forum: C++
    Replies:
    1
    Views:
    417
    Michael DOUBEZ
    Aug 12, 2008
  4. Mosfet

    Loki::SmartPtr syntax

    Mosfet, Apr 10, 2009, in forum: C++
    Replies:
    1
    Views:
    863
    Alf P. Steinbach
    Apr 10, 2009
  5. Gabriel Genellina
    Replies:
    0
    Views:
    479
    Gabriel Genellina
    Nov 13, 2009
Loading...

Share This Page