tags:

views:

284

answers:

3
+2  Q: 

Qt and auto_ptr

I just discovered the concept of an auto_ptr and am liking it! As Qt often requires a QList or QVector<(some QObject or QWidget) *>, is there any concrete reason why auto_ptr should be avoided. If I'm right, it allows you to replace this:

std::vector<MyClass*> vec;
/* add several elements to the vector and do stuff with them */
for(size_t i=0; i<vec.length(); ++i)
{
    delete vec[i];
}
vec.clear();

with somthing much shorter (ie no cleanup)

std::vector<auto_ptr<MyClass>> vec;
/* add several elements to the vector and do stuff with them */
// no need for the delete loop

...Can Qt still work its shared memory magic with auto_ptr's? Does the parent-child automagic memory management still function transparently? Thanks

+8  A: 

Qt has its own smart pointer classes that are in many ways superior to std::auto_ptr, specifically in that some of them can be put into containers with no issues. std::auto_ptr has ownership-transfer copy semantics, and so will not work as expected if you try to put it into a container.

Try using QSharedPointer. It's a reference counted smart pointer that deletes its contained object when there are no more copies of the smart pointer left. Unlike std::auto_ptr there can be multiple copies of the same QSharedPointer at once, and therefore it plays well with containers.

Tyler McHenry
Is a QSharedPointer better comparable to the boost::shared_ptr or the more standard std::tr1:shared_ptr?
Martin York
They have the same semantics, and I can't think of anything about either of them that would be an advantage over the other. But if the project is already using Qt, it wouldn't make sense to introduce a dependency on boost or on TR1 extensions just to use those classes.
Tyler McHenry
+1  A: 

std::auto_ptr cannot be used in std::vector, because std::vector expects to be able to copy its contents, and you can't copy a std::auto_ptr in the normal sense. Copying means winding up with two identical things, and if you had two identical std::auto_ptrs what they pointed to would be double-freed when they went out of scope. (What happens instead is that the auto_ptr being copied from has its internal pointer zeroed out, and the one being copied to is now what the old one used to be.)

Use shared_ptr, which is often available as boost::shared_ptr or on Visual C++ std::tr1::shared_ptr, and which will be in the C++0x standard library, or use whatever Qt has. Those can be copied, and therefore can go into containers.

David Thornley
+1  A: 

If you want a container that has ownership of pointers then look at boost pointer containers.

You put pointers into the container, but like the other containers they are then treated like normal objects which makes it easier to use them with standard algorithms (ie no need to write wrapper classes). When the pointer container goes out of scope it will call delete on all pointers in the container.

boost::ptr_vector v; v.pusj_back(new MyClass(12));

std::for_each(v.begin(), v.end(), DoStuff());

// Destroyed here.

Martin York