Object instantination and initialization
-
Hi!
Should object fields be declared asObject obj;
orObject* obj;
with consequentnew
in universal initializer list anddelete
in destructor?
Why I am asking it - when fields are in the heap memory leaks are a lesser evil on modern PC with 8-16 GB RAM. But when I useObject obj;
declaration in a field the risk of stack breakdown appears. -
-
@raven-worx
Thanks a lot for the link!
Sorry for my ignorance, I am C++ newcomer from Java and C#. Because of garrbage collecting in those languages, C++ memory model seems a bit complicated for me and I'm trying to understand it. -
when fields are in the heap memory leaks are a lesser evil on modern PC with 8-16 GB RAM
Memory leak, seg fault, stack overflow, and race condition are the 4 knights of the apocalypse. They are evil incarnate.
@Tikani said in Object instantination and initialization:
But when I use Object obj; declaration in a field the risk of stack breakdown appears.
Not really, internally Qt allocates almost everything on the heap so for the vast majority of classes
sizeof(OneQtClass)
<=sizeof(int)+sizeof(void*)
@Tikani said in Object instantination and initialization:
and delete in destructor?
Qt normally uses a parent-child system with the ultimate parent allocated on the stack and its destructor will automatically delete all the children recursively. That's what
QObject::setParent
and theparent
argument to anyQObject
is for. ForQWidget
s the parent-child relation is almost obligatory to lay out the visualisation correctly -
-
@VRonin said in Interfaces, abstract, concrete classes and QObject:
This is the flowchart I normally follow, it covers 99% of the cases:
- is it a QObject?
- yes
- can you give it a parent? (for example
moveToThread()
prevents the parent-child relationship)- yes: use a normal pointer and set the parent
- no: connect the
deleteLater()
slot to some signal
- can you give it a parent? (for example
- no
- can multiple places share ownership of the object or pass ownership from one another? (e.g. in containes)
- yes: use
std::shared_ptr
- no: use
std::unique_ptr
- yes: use
- can multiple places share ownership of the object or pass ownership from one another? (e.g. in containes)
- yes
If you need to use the pointer in a function that should not manage ownership but just access (read/write) the object (this covers 90% of use cases) then use a raw pointer argument (use
std::unique_ptr::get()
orstd::shared_ptr::get()
to retrieve the raw pointer from smart pointers) - is it a QObject?
-
@Tikani said in Object instantination and initialization:
If I understand you correctly, I should use RAII, i.e. to attempt to use automatic variables everywhere, avoiding the usage of manual dynamic memory management with help of std::unique_ptr, std::shared_ptr, "make"-functions and so on?
RAII extends to heap allocations too. It's a concept not a design pattern. The rule of thumb is use whatever's more natural, however esoteric this may sound. For example if you want to keep a
QString
or aQObject
as member, auto-storage's perfectly fine. If on the other hand you want to keep a dynamic list ofQObject
s then you need to keep them as pointers and most of the time this'd mean you'd heap allocate the objects.PS. Because @VRonin raised the question, I advise caution when working with
QObject
s and shared pointers (std::shared_ptr
orQSharedPointer
). Shared pointers are okay when an object manages its own lifetime, which forQObject
instances is rather rare, so I'd shy away from using them most of the time.