I come from a Java
background and I recently started to learn Qt
with C++
. While doing some coding a few doubts about objects creation and members declaration have come to me:
Supposing I have a class declared as follows:
ClassA.h:
class ClassA {
private:
MyObject myObj;
QString *declaredArray;
QSharedPointer<MyObject> obj;
public:
void setInfo();
}
ClassA.cpp
void ClassA::setInfo() {
declaredArray = new QString[5];
obj = QSharedPointer<MyObject>(new MyObject, doDeleteLater);
}
What happened in the header where MyObject myObj;
was declared? Was an object of type MyObject
created in the stack and assigned to variable myObj
using a constructor which takes no arguments? Or only an empty variable prepared to store a MyObject
object was declared?
In ClassA.cpp
how would I assign a new object created in the stack to myObj
variable?
declaredArray is an array of int
s created in the heap, should I add a destructor with a delete declaredArray;
to avoid memory leaks?
What happened in the header where QSharedPointer<MyObject> obj;
was declared? Was an empty pointer to MyObject
created? Is the assignment in ClassA.cpp
(obj = QSharedPointer<MyObject>(new MyObject, doDeleteLater);
) correct?
There will be space for myObj
(of the size of MyObject
) wherever ClassA
is allocated (if ClassA
is allocated on the stack, space for myObj
will be on the stack).
If an applicable default constructor exists for MyObject
, and either:
ClassA() : myObj(), declaredArray(NULL), obj(NULL) { }
... then myObj
will be initialized to the default value (MyObject()
).
Also note that any heap-allocated memory you create with new
should be deallocated with delete
on destruction. Therefore, you should also have a destructor:
~ClassA() {
if (delcaredArray != NULL) {
delete[] declaredArray;
}
}
Thanks to RAII, you won't need to destruct myObj
and obj
if explicitly initialized in the ClassA
constructor. If they are not, however, then you will need to explicitly destruct them (e.g., in the case of the shared pointer, decrement the counter).
To answer your other questions explicitly:
What happened in the header where MyObject myObj; was declared? Was an object of type MyObject created in the stack and assigned to variable myObj using a constructor which takes no arguments? Or only an empty variable prepared to store a MyObject object was declared?
myObj
will only be default-constructed (constructed with a constructor that takes no arguments) if the default constructor exists and has been created (implicitly or explicitly).
In ClassA.cpp how would I assign a new object created in the stack to myObj variable?
If myObj
was valid, then myObj = MyObject(...);
(without a new
keyword) would suffice. Note that this would call operator=()
(the assignment operator) on myObj
, so myObj
needs to be already defined for this to be fully defined behavior. If it is already default constructed, then myObj = MyObject(...);
is fine.
declaredArray is an array of int’s created in the heap, should I add a destructor with a delete declaredArray; to avoid memory leaks?
Yes, you should, as shown above.
What happened in the header where QSharedPointer obj; was declared? Was an empty pointer to MyObject created? Is the assignment in ClassA.cpp (obj = QSharedPointer(new MyObject, doDeleteLater);) correct?
The documentation for QSharedPointer shows that its default constructor is a QSharedPointer
pointing to NULL
. If you have a default constructor which is appropriately calling the default constructor for the members, then you should be fine.
A properly constructed (e.g. default or non-default constructed, but initailized) QSharedPointer
can be assigned to using the assignment operator as you showed: (obj = QShardPointer<MyObject>(new MyObject))
.