PDA

View Full Version : Correctly destruction of child objects inside stack object



papercut87
10th August 2016, 08:12
Hi all, i'm trying to solve this problem.

I have a Qt object that does not inherit from QObject:

class A
{
public:
A();
~A();
B * bItem() const;
C * cItem() const;
QList<D *> dList() const;
void addDItem(D*item);
private:
B * m_bItem;
C * m_cItem;
QList<D*> m_dList;
};

#include "a.h"

A::A(){
this->m_bItem = new B;
this->m_cItem = new C;
}

A::~A(){
}

C * A::cItem() const{
return this->m_cItem;
}

B *A::bItem() const{
return this->m_bItem;
}

QList<D*> A::dList() const{
return this->m_dList;
}

void A::addDItem(D*item);{
this->m_dList.append(item);
}
I created an object A:

A a;

and i'm using it like a parameter in a SIGNAL\SLOT connection like this

connect( obj, SIGNAL( sig_message( A ) ), obj2, SLOT( slot_message( A ) ) );

All working fine in the signal\slot mechanism and i can use the A param without problems.
I saw also, when the scope of A param is finished, that the destructor of class A is called correctly.
My only question\doubt is:

how can i destroy the objects ( m_bItem , m_cItem and the list m_dList ) inside A?

They are pointers(and a list of objects pointers).
If use the delete function on those pointers the application crash.(during the emitting signal, maybe the destruction remove the object during the copy...).

Am I using a wrong pattern?

Any suggestion is appreciated.
Thanks in advance.

Lesiok
10th August 2016, 09:31
Use QSharedPointer instead normal pointer.

anda_skoa
10th August 2016, 10:45
how can i destroy the objects ( m_bItem , m_cItem and the list m_dList ) inside A?

You created them with "new" so you need to call "delete" unless they are QObject derived and have a parent :)
For a container like QList you can use qDeleteAll() to call delete on all elements.



They are pointers(and a list of objects pointers).

If these are QObject derived and have a parent then the parent will delete them.



If use the delete function on those pointers the application crash.(during the emitting signal, maybe the destruction remove the object during the copy...).

Because they are deleted multiple times because you have multiple copies of that A object and each executes the same delete on the same pointers.

This is because your A class does not have a copy constructor, so the C++ compiler generates the standard one which does member-by-member copy.
A member-by-member copy of a pointer just ends up with the same pointer in two A objects.

There is a couple of approaches:

- as Lesiok already mentioned by using smart pointers for either the members or for the instance of A that passes through the signal connection
- passing A as a reference or pointer through the signal connection
- implementing a copy constructor and assignment operator in A that creates deep copies of the members

Cheers,
_

d_stranz
10th August 2016, 18:02
- passing A as a reference or pointer through the signal connection

This immediately came to mind when I saw your code. By defining your signal and slots as taking an "A" argument and not an "A*" or "A&", your code is making a new instance of the original A object. As anda_skoa says, because you don't have a copy constructor defined, the default copy constructor does a member-by-member copy of the original "A" instance. In this case, it is simply copying the pointer values themselves, not the objects the pointers refer to. When your signal finishes execution, the copy of A made in the signal is deleted. If you delete the pointers in A's destructor, then the original A is left with "dangling pointers" - pointers to objects that have been deleted and are no longer valid. Next time you go to use one of those pointers, kapow!

papercut87
12th August 2016, 17:36
Thanks to all men!

I will try with one of the different solutions that you seggested me.
I was sure that there was something wrong with my current implementation.