Object Usage and Destructors

Started by
24 comments, last by Josheir 6 years, 10 months ago

class A
{
private:
    B* objB;

public:
    A()
    {
        objB = new B();
    }

    ~A()
    {
        delete objB;
    }
}

So, what if objB = new B() was never used?

Would B not be an object and therefore no need to delete it (it would be a pointer to no object)?

And before smart pointers: if there are objects of B in A and they need to be destructed do we need to use the new/delete so that B's destructor can handle them?

Almost got it I think,

Josheir

Advertisement

Because when you create a class instance like this,


SomeClass SomeClassInstance;

it gets created on stack memory which is automatically managed. You don't have to delete the object instance here, it is automatically done.


And when you create a class instance like this with new word (Which you did not use)


SomeClass* SomeClassInstance = new SomeClass();

It gets created on heap memory and you're required to manually delete it when you're done with it. The destructor is then called when you delete it.

EDIT: Whoops, did not knew it already has better answers.

If you didn't create an object and make objB point to it, then no, there's nothing to clear up regarding that objB pointer. It's just a 'dangling' pointer that isn't doing anything.

(It doesn't make sense to say "Would B not be an object" - B, in this example, is a class. The objB variable is a pointer, and it points to an instance of class B.)

The objects inside B are for B to clear up. Whether you made the instance of B via 'new' or not is irrelevant.

So, what if objB = new B() was never used?

Undefined behavior. If you had initialized objB to nullptr, then it would be pretty safe to call delete. Using delete on nullptr initialized pointers is fine. Using delete on uninitialized pointers would have undefined behavior.

All right last try...

if new and delete are used the advantage is that the destructor is called so the object can handle the inside objects.

if the there is an internal object and it is not a pointer, the destructor will be called when it goes out of scope.

And finally if a pointer to an object is used and there is objects in it that need to be destroyed than you should have used new/delete so that the destructor is called to handle these objects (once again not using smart pointers!)

Phew I'm hoping this is it, thanks,

Josheir

That looks roughly right.

Just remember a pointer to something is not the instance itself. A pointer points to an object instance. Object instances are created and destroyed independent of the pointer that may point to them.

You can have many pointers that all point to the same object instance. You may have hundreds of pointers that may point to the object, but you should only have one thing that actually controls the lifetime of the instance; only one thing should allocate or destroy the object instance itself. These days usually that one thing is a container or smart pointer.

Regarding new and delete, in modern code it is very rare to use either of those. These days if you see new and delete in the source code you should probably ask if it would be better to use a more modern option. Container classes and smart pointers are generally the better way to create and destroy objects and control their lifetimes, although you will still use pointers to point to those objects. They are a little misnamed, but smart pointers control the lifetime of the object instance, and they ensure the object instances are properly destroyed even if there are strange code paths like exceptions.

/EDIT: Also a gentle reminder that this is For Beginners, not the more technical forums.

"if new and delete are used the advantage is that the destructor is called"

No.

The destructor is called for any object when that object is destroyed. The object is destroyed when it goes out of scope, or the object containing it is destroyed.

"if there is an internal object and it is not a pointer, the destructor will be called when it goes out of scope."

If by 'internal object' you mean a member of some enclosing object, then it is destroyed when the enclosing object is destroyed.

If by 'internal object' you mean a local variable inside a function or whatever, then it is destroyed when it goes out of scope.

"And finally if a pointer to an object is used and there is objects in it that need to be destroyed than you should have used new/delete so that the destructor is called to handle these objects (once again not using smart pointers!)"

Not exactly. It doesn't make sense to say "you should have used new", because (as above) using new makes absolutely no difference to whether a destructor is called. The destructor is called when the object is destroyed, no matter how it gets destroyed, or how it got created.

If you created an object with 'new', and don't later 'delete' it when the pointer that refers to it has gone, that's a memory leak. The object still exists somewhere in memory but you can never use or reach it, so that's not idea.

The purpose of 'new' is to create an object that will outlive the current scope. The most common situation where this happens is that you call 'new' inside a constructor to create a sub-object, and assign it to a pointer inside the object. This is what my last code example did with objB. There are likely to be other functions that operate on the object during the running of the program, then at the end, when the enclosing object gets destroyed, the destructor for that object ensures that all sub-objects are cleaned up, by explicitly calling 'delete' on anything that was created via new.

You might be wondering why we'd have a pointer inside of a class and create an object via new, instead of just having the object inside the class directly. Usually, if you can, you do want to just contain the object directly and avoid all the pointer stuff. But there are various reasons why that may not be the ideal approach; reasons that you probably don't need to worry about yet.

Sounds great, I just wanted to understand the past ways too, I think it's important.

When 'new' was being used and an instance of an object was pointed too using it, did people ever instead put the object in with the data members and point to it for example in the constructor?

Besides what we've mentioned, what were the other pros and cons of using new/delete versus using this more regular non new/delete method of pointing to an instance.

Thank you,

Josheir

That question doesn't make sense to me. Could you rephrase, being very specific with your terms?

In an object that has a different object,

new can be used to create a pointer to that object as shown.

What about creating a pointer to that object that is a data member instead?

Is this good or bad for what reasons?

Thank you,

Josheir

This topic is closed to new replies.

Advertisement