🔒 Locked
Smart pointer question
Advertisement
Original Post
I know not to use std::auto_ptr inside of a container because auto_ptr's are not CopyConstructible (STL concept). In order to get around this, why can't someone just write their own AutoPtr template class and declare the internal pointer to be mutable? After all, if the pointer is just going to be the owner of a resouce, I don't see a need to use a shared_ptr. A little hacky, yes, but I consider it better than maintaining a reference count.
Because making the member mutable would not solve the problem!
The whole problem is that the pointer cannot own the resource if you want to use it with an STL container.
i think the problem is people are not understanding the intended purpose of std::auto_ptr, there is already a hint in its name "auto" as in automatic variable you know the storage class auto that is implicitly declared with variables inside function/block scope that is the default storage class, e.g.
So auto_ptr makes heap allocated objects act like variables with storage class of auto, so once the end of the function/block scope is finished its deleted automatically.
auto_ptr's main intent is to be used for RAII techniques & exception code, so for what its intended for its appropriately designed.
note that boost::shared_ptr is in c++ Library TR 1 standard, std::tr1::shared_ptr
void foo() { auto int bar; //auto is normally implicitly declared { auto int foobar; }}So auto_ptr makes heap allocated objects act like variables with storage class of auto, so once the end of the function/block scope is finished its deleted automatically.
auto_ptr's main intent is to be used for RAII techniques & exception code, so for what its intended for its appropriately designed.
note that boost::shared_ptr is in c++ Library TR 1 standard, std::tr1::shared_ptr
Quote:
Original post by Toolmaker
Problem solved:
http://www.lepouya.com/upload/SmartPointer.h
Toolmaker
He said he didn't want to use reference counting.
Also, the implementation you provided does not allow hierarchial conversions.
Quote:
Original post by Toolmaker
Problem solved:
http://www.lepouya.com/upload/SmartPointer.h
Toolmaker
Not exception safe (Reset) and fails under self-assignment. Just use the boost smart pointers.
Enigma
Quote:
Original post by antareus
I know not to use std::auto_ptr inside of a container because auto_ptr's are not CopyConstructible (STL concept). In order to get around this, why can't someone just write their own AutoPtr template class and declare the internal pointer to be mutable? After all, if the pointer is just going to be the owner of a resouce, I don't see a need to use a shared_ptr. A little hacky, yes, but I consider it better than maintaining a reference count.
Actually, one of the original forms of the standard library allowed std::auto_ptr to compile inside an STL container without errors or warning, and all seemed well. Then one day someone decided to use an algorithm on the container class, and for lack of a better term, something hit the fan hard.
Consider std::sort() an implementation in pseduo-code might look something like:
std::sort(begin, end) { if (begin == end) return; T pivot = get_pivot(begin, end) iterator middle = partition(begin, end, pivot) sort(begin, middle) sort(middle, end)}This isn't even close to right for a quicksort algorithm, but it illustrates the underlying problem: there's a temp value copy made in the algorithm, which removes one of the stored objects from ownership by the container. And then the recursion removes even more stored objects.
Basically, this a problem that can't be addressed by modifying just std::auto_ptr. You have to create an entire standard library implementation that plays happily with std::auto_ptr like objects that have unusual copy construction semantics. You might be able to create your own std::auto_ptr analogue that can be compiled in a standard container, but be very careful what algorithms and possibly even member functions you use with that container.
m_Pointer = p; m_RefCount = new size_t; *m_RefCount = 1;If new throws an exception the reference count is not set, while the pointer is. Also, the copy constructor and assignment fail if the object to be copied is not initialized.
I don't know what Polymorphic OOP meant by hierarchial conversions, but your code does not allow the following:
SmartPtr<Derived> d(new Derived);SmartPtr<Base> b = d;As others have said: use boost::shared_ptr, why reinvent the wheel?
Well, I know what an auto_ptr is. And it makes perfect sense why it blows up with sorting. I just find it strange that in order for a container to safely own a pointer and delete it when it is done, that it must be reference counted.
What a pain.
Why not just write STL wrapper classes (like vector_ptr, etc) that handle this fact for you? The ptr suffix is okay, but I'd prefer a name like "PossessiveVector" or the like...something that expresses the fact that the container is responsible for the lifetime of the pointers it holds.
What a pain.
Why not just write STL wrapper classes (like vector_ptr, etc) that handle this fact for you? The ptr suffix is okay, but I'd prefer a name like "PossessiveVector" or the like...something that expresses the fact that the container is responsible for the lifetime of the pointers it holds.
Quote:
Original post by twanvl
I don't know what Polymorphic OOP meant by hierarchial conversions
I was refering to standard pointer conversions through a type hierarchy that work with regular pointers and other smart pointer types, such as shared_ptr (and in his case, his smart_ptr implementation doesn't work with pointers of further cv-qualification either).
I.E.
class a { public: virtual ~a() {} };class b : public a {};SmartPtr< b > b_ptr( new b );SmartPtr< a > a_ptr = b_ptr; // Will not work, and no function is provided to make it work// AlsoSmartPtr< const b > const_b_ptr = b_ptr; // Same problem as aboveOf course, that doesn't affect its ability to be safely used in a container, but it's another feature which mimmicks the use of regular pointers and adds no runtime cost compared to his current implementation, yet is not supported by the template -- further reason to just use another smart pointer type, such as shared_ptr instead.
Quote:
Original post by Toolmaker
Well, it doesn't fail when you assign the auto pointer to itself, since it increases the refcount before killing the old pointer.
It NULLs both the pointer and reference count, thus destroying the pointer and leaking both pointer and reference count. Don't just take my word for it, try it:
SmartPtr<T> ptr(new T);ptr = ptr;ptr->func(); // null pointer exceptionEDIT: I grabbed and compiler and tested it, and after fixing another error (your constructor-from-T-pointer uses uninitialised values) it does indeed demonstrate the behaviour I expected.
Enigma
[Edited by - Enigma on December 24, 2004 9:56:47 AM]
Ok, thanks for the replies. I'll fix those so at least it works. The reason I wrote the smart pointer was mainly a learning experience. I needed a smart pointer, and decided to write my own so as a nice learning experience.
I'll fix those errors which I can fix for now. How would I go on fixing the errors with the hierachical conversions?
Toolmaker
I'll fix those errors which I can fix for now. How would I go on fixing the errors with the hierachical conversions?
Toolmaker
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement