1

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 ints 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?

demonplus
  • 5,613
  • 12
  • 49
  • 68
  • 1
    What you need is to read a good C++ book. (And tip: don't assume _anything_ carries over from what you learnt in Java. Even though Qt does have a Java-ish feel to it in a lot of places.) – Mat Jan 08 '15 at 05:41
  • If you are starting to learn C++ , I don't think starting with QT is the easiest way to go. QT uses allot of what C++ can offer, and you might bump into too much information at once (templates, macros , smartpointers , etc).If you are not forced to use QT (meaning you're not assigned to a project with QT) try going for some simpler frameworks/libraries (OpenGL for example). – MichaelCMS Jan 08 '15 at 12:48

1 Answers1

3

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:

  1. You define an explicit default constructor as follows:
    ClassA() :
        myObj(),
        declaredArray(NULL),
        obj(NULL) { }
  1. You have no constructors declared, thus causing an implicitly-declared default constructor to be added by the compiler, which roughly resembles the above functionality.

... 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)).

EyasSH
  • 3,679
  • 22
  • 36
  • Good catch, I'll clarify. – EyasSH Jan 08 '15 at 06:05
  • *"But the object won't be default constructed."* -- If the `MyObject` class has a default constructor, then `myObj` definitely will be default constructed, without any intervention on the part of the author of the `ClassA` constructor. – Benjamin Lindley Jan 08 '15 at 06:05
  • @BenjaminLindley are you suggesting `MyObject` will be default constructed if `MyObject` had a default constructor and `ClassA` did not? – EyasSH Jan 08 '15 at 06:07
  • If `MyObject` has a default constructor, then so does `ClassA`, unless `ClassA` has another user declared constructor. But either way, yes, if `MyObject` has a default constructor, then it will be default constructed when its owning `ClassA` is constructed. – Benjamin Lindley Jan 08 '15 at 06:09
  • That sounds vaguely familiar. My reading of the "implicitly-declared default constructor" section here (http://en.cppreference.com/w/cpp/language/default_constructor) is that an "empty initializer list" means that members are not initialized. I guess you're suggesting "empty initializer list" means an initializer list for all base classes and members, with empty parameters. I'll double check another source to figure out.. you might be right here. – EyasSH Jan 08 '15 at 06:11
  • For classes with constructors (any constructors whatsoever), there is no such thing as a "not initialized" state. There's either an object or there isn't. And if there is, then it is initialized (by one of its constructors). – Benjamin Lindley Jan 08 '15 at 06:15
  • I believe you can still have a "not initialized" state if you have an explicit constructor and neglect to name a member in its initializer list, no? Would that just be default constructed as well? – EyasSH Jan 08 '15 at 06:18
  • 1
    Yes, it would be default constructed. Only trivially constructible types (primitives, and aggregate classes with no user declared constructors) are left uninitialized, unless explicitly initialized. http://ideone.com/f4VL3d – Benjamin Lindley Jan 08 '15 at 06:32