October 10, 2011

fluca1978 fluca1978
Lab Rat
529 posts

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:

  1. class MyWidget : public QWidget{
  2. ...
  3.   QList<TableViewHandler*> handlers;
  4. };

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:

  1. QList<TableViewHandler*>* handlers = new QLits<TableViewHandler*>();
  2. // initialize the list
  3. ...
  4. QList<TableViewHandler>& ref = *handlers;
  5. 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?

5 replies

October 10, 2011

Gerolf Gerolf
Robot Herder
3252 posts

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:

  1. class MyWidget : public QWidget{
  2.     MyWidget(QList<TableViewHandler*>& _handlers, QWidget* parent);
  3.     ...
  4.     QList<TableViewHandler*>& handlers;
  5. };
  6.  
  7. MyWidget::MyWidget(QList<TableViewHandler*>& _handlers, QWidget* parent):
  8.     QWidget(parent),
  9.     handlers(_handlers) // here, a reference is given to the object, as the member is a reference
  10. {
  11. }
  12.  
  13. //+++++++++++++++++++++++++++++++++++++++++++++++++++
  14.  
  15. foo()
  16. {
  17.     QList<TableViewHandler*>* handlers = new QLits<TableViewHandler*>();
  18.     // initialize the list
  19.     ...
  20.     // QList<TableViewHandler>& ref = *handlers; this is not needed
  21.     MyWidget* w = new MyWidget( *handlers ); // here, a reference is given to the constructor, as the parameter is a reference
  22.     ...
  23. }

If you go this way, you MUST ensure that the heap object will not be deleted, before the widget!

 Signature 

Nokia Certified Qt Specialist.
Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

October 10, 2011

fluca1978 fluca1978
Lab Rat
529 posts

But in this case the pointer to heap data will be lost when the method goes out of scope, so the only way to get the address of the data to be deleted is thru the &reference, right?

October 10, 2011

koahnig koahnig
Area 51 Engineer
2889 posts

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.

October 10, 2011

fluca1978 fluca1978
Lab Rat
529 posts

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.

October 10, 2011

Gerolf Gerolf
Robot Herder
3252 posts

This can be done in an easy way:

  1. class MyWidget : public QWidget{
  2.     MyWidget(QList<TableViewHandler*>& _handlers, QWidget* parent);
  3.     ...
  4.     QList<TableViewHandler*> handlers;
  5. };
  6.  
  7. MyWidget::MyWidget(QList<TableViewHandler*>& _handlers, QWidget* parent):
  8.     QWidget(parent),
  9.     handlers(_handlers) // <-- here, the data is copied
  10. {
  11. }
  12.  
  13. //+++++++++++++++++++++++++++++++++++++++++++++++++++
  14.  
  15. foo()
  16. {
  17.     QList<TableViewHandler*> handlers;
  18.     // initialize the list
  19.     ...
  20.     MyWidget* w = new MyWidget( handlers ); // here, a reference is given to the constructor, as the parameter
  21.                                             // is a reference, but it will be copied behind the scenes, so the
  22.                                             // automatic deletion on method end is ok.
  23.     ...
  24. }

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…

 Signature 

Nokia Certified Qt Specialist.
Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

 
  ‹‹ [SOLVED] how to create a map of actions      [SOLVED] Private object when they need to be allocated on the stack and when on the heap? ››

You must log in to post a reply. Not a member yet? Register here!