What do you think? Is this correct or are there memory leaks?
Source:
#include <QList.h>
#include <boost/shared_ptr.hpp>
#include <iostream>
class A {
private:
int m_data;
public:
A(int value=0) { m_data = value; }
~A() { std::cout << "destroying A(" << m_data << ")" << std::endl; }
operator int() const { return m_data; }
};
int _tmain(int argc, _TCHAR* argv[])
{
QList<boost::shared_ptr<A> > list;
list.append(boost::shared_ptr<A>(new A(6)));
std::cout << int(*(list.at(0))) << std::endl;
return 0;
}
Output:
6
destroying A(6)
-
It is difficult to suggest anything without knowing why the list of
shared_ptr
s ofA
objects exist in the first place.Take a look at the ownership semantics of smart pointers. Maybe of help to you.
Some other things that can be improved:
1. Use initializer lists in ctor like:
class A { private: int m_data; public: A(int value=0) : m_data (value) {} // ....
2.
int _tmain(int argc, _TCHAR* argv[])
is not a Standard signature;Use
int main(int argc, char* argv[])
or just:
int main()
Wolfgang Plaschg : I'm not sure what you mean with your first point. Where should I use initializer lists? `_tmain` was the default when using the Visual Studio wizard but thank's for that hint!Skurmedel : _tmain(int argc, _TCHAR* argv[]) is a valid signature on VC++ :). It's a main method that takes either multibyte or unicode arguments, depending on a switch in VS. There's also a int wmain(int argc, wchar_t *argv[]).dirkgently : An implementation can provide N different signatures of main. The language Standard defines only two (I mentioned above).Skurmedel : Yes that's true. But as I said, it's perfectly valid on VC++. -
This code looks perfectly fine.
If you're seeking advice perhaps you could provide more info on the purpose of using shared_ptr with QList, there might be a "Qt" way of doing this without pulling the big guns such as shared_ptr.
Wolfgang Plaschg : I was playing around with QList and when doing so you have to take care of the list elements by yourself. Which is annoying, obviously. I haven't found a Qt way for using smart pointers.Idan K : that's not entirely correct. you could use Qt's object ownership tree like layout, passing the QList as the owner of each object inserted to it. it's a very useful technique when working with Qt. read more about it here: http://doc.trolltech.com/4.5/objecttrees.htmlParker : @daniel That's not a option here, as the parents and children have to be QObject subclasses for that to work. QList isn't a QObject so it's a no go even if A inherited from QObject.Idan K : true, totally forgot that QList isn't a QObject! this can still be useful though, depending on the context of using that QList. -
It seems correct. Boost's shared_ptr is a reference counting pointer. Reference counting is able to reclaim memory if there are no circular references between objects. In your case, objects of class A do not reference any other objects. Thus, you can use shared_ptr without worries. Also, the ownership semantics allow shared_ptrs to be used in STL (and Qt) containers.
-
If you're not using a smart pointer, you have to delete the list elements by yourself.
Source:
#include <QList.h> #include <boost/shared_ptr.hpp> #include <iostream> class A { private: int m_data; public: A(int value=0) { m_data = value; } ~A() { std::cout << "destroying A(" << m_data << ")" << std::endl; } operator int() const { return m_data; } }; int _tmain(int argc, _TCHAR* argv[]) { QList<A *> list; list.append(new A(6)); std::cout << int(*(list.at(0))) << std::endl; return 0; }
Output:
6
Not good.
Parker : Then just remove the "new" operator and the A objects will be deconstructed when the the QList is. -
Qt 4.6 now comes with smart pointers, jfyi.
0 comments:
Post a Comment