Class instantiation, which is the best way and why?

Hi All,

Just learning about classes and trying to understand the different ways you can create an object. It looks like from code you can do this 3 ways, is this correct. One using a pointer, one using pointer new and other using standard. Which one is best to use and why? I know there is different types of memory but looking at the best way of doing this without problems.

1
2
3
4
5
6
7
8
9
    
    Level *test1;
    Level *test2 = new Level();
    Level test3;
    
    test1->a = 1;
    test2->a = 2;
    test3.a = 3;
This entirely depends on the context of what you're doing. Most small objects can be instantiated in way 3. Way 1 isn't complete, because it will almost always then be made to refer to a new or an existing object on the stack. I'd change way 2 into
1
2
std::unique_ptr<Level> test2a (new Level); //way 2a
std::shared_ptr<Level> test2b (new Level); //way 2b 
Line 6 is undefined behaviour (most likely, a crash), because you haven't initialised test1 to actually point to anything.

Your creation and use of test2 and test3 are fine. It all depends what you want the lifetime of the object to be. Do you need to create it on the heap, or can it be on the stack?
@koko82

Where did you pick up the idea you could use an uninitialized pointer?

You could do this (i.e. create the object after defining the pointer test1:

Edit: make code C++ Shell friendly.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>

class Level {
public:
    Level() : a(0) { std::cout << "Level::Level() [value = " << a << "]\n"; }
    ~Level() { std::cout << "Level::~Level() [value = " << a << "]\n"; }
    int a;
};

int main() {
    Level *test1 = NULL; // good practice to initialize pointer variable to NULL
    Level *test2 = new Level; // no need for () in C++ when using default contructor
    Level test3;

    test1 = new Level(); // create new Level
    
    test1->a = 1;
    test2->a = 2;
    test3.a = 3;

    delete test1; // and remember to delete the objects we new-ed
    delete test2; // (the danger of forgetting to do this is why you
                  // should use unique_ptr or shared_ptr

    return 0;
}


Andy
Last edited on
Definitely use the normal (3rd) way (if possible).
This way you won't have to dynamically allocate memory which also makes it a little bit faster and you don't have to care about the scope of the Object because you know when it's going to die.


If you have to use a pointer use one of the C++ memory-managing-classes std::shared_ptr or std::unique_ptr to prevent memory leaks
Last edited on
Thank you all for your responses most helpful.

andywestken - I've seen some examples online

Gamer2015 - if I need to use the 3rd way do I need to do anything with the deconstructer? Or will the default deconstructer suffice.

Is this new way unique & shared pointer, I am looking at some books doesn't seem to cover those?
if I need to use the 3rd way do I need to do anything with the deconstructer? Or will the default deconstructer suffice.


You mean the destructor. There is no deconstructor. Based on what you wrote, you have to delete the objects test1 and test 2. If the level class also instantiates dynamic resources then yes its destructor might have to be coded to deal with that. Using smart pointers and STL containers can reduce your responsibility as a programmer, but you always have to plan for dealing with dynamic memory somehow either by choosing a smart pointer or container, or by releasing the resource yourself.

Honestly, you will have to learn both ways because in any given program chances are there will be objects that are constructed in a variety of ways and you need to know how to deal with each and every circumstance. Don't assume that you can get a way with always doing it one way or the other.
which is the best way and why?

If you just need the object to live for the duration of a function call you should instantiate it on the stack (the 3rd way.) Then you don't have to worry about deleting it, or using a smart pointer.

If you need the object to live beyond the lifetime of the function it was created in, then it needs to be allocated on the heap; preferably using some sort of smart pointer.

Andy
Last edited on
I've seen some examples online

If your source of examples is telling you that you can de-reference an uninitialized pointer, then you need a better source if examples.

Are you sure those examples didn't initialise the pointer to actually point to something, before dereferencing it?
Thanks all for your help much appreciated. I will start to use the new smart pointer method as it seems you don't have to worry about deleting it from memory.
Topic archived. No new replies allowed.