Creating a pointer and using a reference, what about deletion?
-
Hi,
I've got still a bit of confusion between the usage of pointers and references. In a widget I've got I'd like to use a list as a reference:@class MyWidget : public QWidget{
...
QList<TableViewHandler*> handlers;
};@The widget above is constructed in a method connected as a slot, so I allocate the list on the heap to avoid it being destructed due to the scope of the method call:
@
QList<TableViewHandler*>* handlers = new QLits<TableViewHandler*>();
// initialize the list
...
QList<TableViewHandler>& ref = handlers;
MyWidget w = new MyWidget( ref );
@Now the doubt I've got is about the deletion: since the list has been constructed on the heap, and I've using a reference, is it sure to delete in the constructor using &handlers as address?
-
Hi,
you misunderstood refernces. in your example, in löine 4 you create a reference of the heap object from line 1, but the call on line 5 will copy it, as the member of the widget is a value and not a reference.
If you use a reference inside the widget, it would be:
@
class MyWidget : public QWidget{
MyWidget(QList<TableViewHandler*>& _handlers, QWidget* parent);
...
QList<TableViewHandler*>& handlers;
};MyWidget::MyWidget(QList<TableViewHandler*>& _handlers, QWidget* parent):
QWidget(parent),
handlers(_handlers) // here, a reference is given to the object, as the member is a reference
{
}//+++++++++++++++++++++++++++++++++++++++++++++++++++
foo()
{
QList<TableViewHandler*>* handlers = new QLits<TableViewHandler*>();
// initialize the list
...
// QList<TableViewHandler>& ref = handlers; this is not needed
MyWidget w = new MyWidget( *handlers ); // here, a reference is given to the constructor, as the parameter is a reference
...
}
@If you go this way, you MUST ensure that the heap object will not be deleted, before the widget!
-
You mix two things.
In calling list to methods you may use references (&) and pointers (*). They are basically similar from the overhead point of view. You do not copy the data.
Within the method the references are typically easier to use. You do not need the *. So far nothing with memory allocation.If you use in a method a pointer and you allocate memory, you have to make sure that the memory is deleted prior to exit of the method. Otherwise you get a memory leak.
You may hand allocated memory to a method through a pointer. You may delete/release this memory in the method, that is possible. However, you have to make sure that you are not using the pointer again somewhere else.
Edit: If you are not sure about the reference and pointer concept, it is better to keep it simple. Release the meory where you have allocated it.
-
Thanks, it is clearer now.
My problem is that I need to initialize a widget with some custom (i.e., user defined) data, so I build the data, pass it to the widget and then deallocate it when the widget is destructed. This does not follow your principle of deallocating where the allocation occurs, but I don't know how to do otherwise. A solution could be to copy all the built data within the widget, not storing so the pointers. -
This can be done in an easy way:
@
class MyWidget : public QWidget{
MyWidget(QList<TableViewHandler*>& _handlers, QWidget* parent);
...
QList<TableViewHandler*> handlers;
};MyWidget::MyWidget(QList<TableViewHandler*>& _handlers, QWidget* parent):
QWidget(parent),
handlers(_handlers) // <-- here, the data is copied
{
}//+++++++++++++++++++++++++++++++++++++++++++++++++++
foo()
{
QList<TableViewHandler*> handlers;
// initialize the list
...
MyWidget* w = new MyWidget( handlers ); // here, a reference is given to the constructor, as the parameter
// is a reference, but it will be copied behind the scenes, so the
// automatic deletion on method end is ok.
...
}
@As QList is an implicitly shared class, the copy will be cheap as it only copies a simple pointer to the contained data and the deletion of the stack object will not really delete the data, only decrease the ref count and everything is safe. Thanks to the implicitly shared classes, it's cheap and easy...