QSharedPointer Usage
-
wrote on 10 Dec 2010, 19:53 last edited by
I just have a general question here. Is it a good idea to use a QSharedPointer or a QScopedPointer to handle widgets? For example:
@
QSharedPointer<QToolButton>(new QToolButton);@I have been trying to make this work properly within a psuedo widget factory i have made( as the application has thousands of widgets) and I want to make sure that the memory is de-allocated properly. But everytime i try to implement this i recieve a seg fault. here is a code snippet.
@QToolButton* ButtonFactory::createButton_GenericButton(int height,int width,const QString &text,const QString &id,const QString &styleSheet,const QIcon &buttonIcon)
{
ButtonFactory::button = QSharedPointer<QToolButton>(new QToolButton);ButtonFactory::instanceString = QSharedPointer<QToolButton>(new QToolButton);
ButtonFactory::button->setStyleSheet(styleSheet);
ButtonFactory::button->animateClick(50);
ButtonFactory::button->setMinimumHeight(height);
ButtonFactory::button->setMinimumWidth(width);
ButtonFactory::button->setText(text);
ButtonFactory::button->setObjectName(""+id+""+ButtonFactory::instanceString->setNum(ButtonFactory::nextInstance));
ButtonFactory::button->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
ButtonFactory::button->setIcon(buttonIcon);
ButtonFactory::nextInstance++;
/// I am not sure if this line is valid
return ButtonFactory::button.data();
}
@
but simply using QSharedPointer OR QScopedPointer in this manner seg faults it and I am not sure if it is due to the manner in which i am calling the function later ( located in another class that builds widgets into a frame with a layout).
ideas?
-
wrote on 10 Dec 2010, 22:35 last edited by
It is a good idea to use QScopedPointer for exception safety and QSharedPointer for resource management. However, it is not recommended for QWidget derived classes (or QObject classes to a lesser degree). QWidgets are owned by their parent, and since they are reparented when put into layout, they can't be used in a QSharedPointer unless they are never parented (or the parent is never destroyed while they are a child).
-
wrote on 13 Dec 2010, 13:32 last edited by
ok, that makes sense, thanks
-
wrote on 13 Dec 2010, 14:01 last edited by
ButtonFactory::button seems to be a member of your class. As soon as you call your method a second time, you assign a new pointer to this variable, the reference count of the old one will go to 0 and your first button is deleted. This could be a cause for your segfault.
The API docs mentions this:
bq. "QSharedPointer:: operator=":http://doc.qt.nokia.com/latest/qsharedpointer.html#operator-eq
Makes this object share other's pointer. The current pointer reference is discarded and, if it was the last, the pointer will be deleted.QScopedPointer is even worse:
bq. "QScopedPointer ":http://doc.qt.nokia.com/latest/qscopedpointer.html#details
The QScopedPointer class stores a pointer to a dynamically allocated object, and deletes it upon destruction. [...] QScopedPointer guarantees that the object pointed to will get deleted when the current scope disappears.So, as soon as you exit from your method, the just now created tool button is destroyed and the calling method receives an invalid pointer.
As Bradley already mentioned, as long as you give your QWidgets and QObjects a proper parent, Qt takes care of deleting all the stuff for you and theres hardly any need to worry for this.
-
wrote on 13 Dec 2010, 14:34 last edited by
Thanks for the help. I knew if i parented properly then they would be released upon destruction, I just have a hard time leaving memory management to the framework. I have had alot of issues with this in C# and old habits die hard. But you are correct for my purposes there is no real need.
-
wrote on 13 Dec 2010, 14:45 last edited by
It's the other way round, that can do you some harm. If you destroy the objects yourself and if you set the parents correctly, it can happen, that your objects will be destroyed twice, which will lead to segfaults. Even the Trolls stepped into this trap in their official docs (see the "Getting started example is buggy":http://developer.qt.nokia.com/forums/viewthread/2253/ thread), although in a slightly different way.
3/6