On Thu, Nov 14, 2002 at 11:38:25PM -0800, Duane Murphy wrote:
--- At Thu, 14 Nov 2002 22:36:40 -0600, Stephen Crowley wrote:
Accessing this here is accessing it as a raw pointer outside of the shared_ptr. In a word...dont do that.
I had this problem before but I was able to work around it. I dont have a good suggestion for a solution. Basically, architecturally, I arranged to not need to save things this way. In my case I ended up actually passing in a shared_ptr to solve the problem. You can duplicate a shared_ptr, you cant duplicate a raw pointer this way.
I have found this to be a difficult thing to deal with in a couple of corner cases. Where I wanted the raw pointer to know that it was shared, but I couldnt do that. This would be an intrusive shared_ptr implementation rather than the current non-intrusive one. In an intrusive implementation, the count information is actually part of the shared object rather than an extra pointer. There are certain advantages to the intrusive model. Of course it has is draw backs as well.
Hi Duane. Thanks for the help. I considered redesigning my classes so that using 'this' wouldn't be necessary, however I decided that it would complicate things unnecessarily. I've created two new templates calle, one called smart_ptr which is based on shared_ptr, and one called smart_class. Basically, when a smart_class is constructed, it initializes thisptr of type smart_ptr<T> to 'this'. When a smart_ptr is intialized with a standard pointer(s), either through a constructor or assignment, it first checks to see whether s->thisptr is initialized. If it is, it simply does a normal copy. If it isn't initialized, it creates a new shared_ptr to point to it. Also, smart_ptr checks the reference count every time it is destroyed or re-assigned, and if the count is 2 then it resets "get()->thisptr" as well, this is necessary because the smart_class is self referencing and will never get deleted otherwise. I've tested it for a while I think I have in working in just about every case that I need. The only drawbacks are that you cannot instantiate a smart_class on the stack, or 'delete' it'. Also, you MUST overload the copy consructor for smart_class derived classes, if this wasn't forced then the default copy would duplicate thisptr, which obviously isn't what we want. I can't help but think that I am doing something very weird here, but it seems to work. The header and this example code can be found at http://groups.yahoo.com/group/Boost-Users/files/smart_ptr/ #include "smart_ptr.h" #include <iostream> using namespace std; class MyClass : public smart_class<MyClass> { public: MyClass() { cout << "constructed " << this << endl; }; MyClass(MyClass &m) { }; ~MyClass() { cout << "deleted " << this << endl; }; smart_ptr<MyClass> makeChild() { smart_ptr<MyClass> child(new MyClass); child->parent = this; // this actually works return child; } smart_ptr<MyClass> parent; }; smart_ptr<MyClass> make_child() { smart_ptr<MyClass> parent(new MyClass); return smart_ptr<MyClass>(parent->makeChild()); } main() { smart_ptr<MyClass> child; child = make_child(); cout << "child = " << child.get() << " child->parent = " << child->parent.get() << endl; cout << "resetting child->parent, it should be deleted as the last reference is gone" << endl; child->parent.reset(); cout << "all done, child should be deleted when main() exits" << endl; } -- Stephen