-5

I am new to C++. I have written below code for understanding how constructor and destructor works in C++.

#include<iostream>

using namespace std;

class Line
{
    private:
        Line();
    public:
        int length;
        static void getInstance(Line* objLine);
        ~Line();
};

void Line::getInstance(Line* objLine)
{
    if(objLine == NULL)
    {
        objLine = new Line();
    }
}

Line::Line()
{
    cout<<"In the Constructor"<<endl;
}

Line::~Line()
{
    cout<<"In the Destructor"<<endl;
}

int main()
{
    Line* objLine = NULL;
    Line::getInstance(objLine);
    return 0;
}

I have read that destructor of a class is invoked when object goes out of scope. In above code object is handled by objLine which is a local variable. So at the end of the main i have expected destructor to be invoked. But it is never getting invoked. Any one please tell me when destructor is invoked in above case

Durgesh Tanuku
  • 1,124
  • 2
  • 10
  • 26
  • 1
    `objLine` goes out of scope as `main` ends, but `objLine` is *not* an instance of `Line`, it is simply a pointer. So a pointer goes out of scope at the end of `main`. It has no destructor. If you had written `Line objLine` instead, the destructor would have executed as `objLine` went out of scope. – Magnus Hoff Jun 08 '15 at 11:15
  • For software beyond education I suggest using shared pointers, which invoke the destructor, when variable goes out of scope. – Simon Jun 08 '15 at 11:16
  • Possible duplicate of http://stackoverflow.com/questions/10081429/when-is-a-c-destructor-called – Rndp13 Jun 08 '15 at 11:34

3 Answers3

9

In C++, the destructor is called when a variable goes out of scope, or when delete is called on an object created with new.

You use new to create an object, but never use delete, hence the destructor is never called.

If your code would be like this:

int main() {
   Line objLine;
}

the destructor is called.

Bart Friederichs
  • 33,050
  • 15
  • 95
  • 195
2

You need to clean up your own memory in this case

int main()
{
    Line* objLine = NULL;
    Line::getInstance(objLine);
    delete objLine;
    return 0;
}

This is because you used new to allocate the memory, so it won't automatically clean itself up after it falls out of scope. You need to clean up the memory using delete

As @StefanoSanfilippo mentioned, you also need to change your getInstance function to

void Line::getInstance(Line*& objLine)
Community
  • 1
  • 1
Cory Kramer
  • 114,268
  • 16
  • 167
  • 218
  • 2
    Actually, this doesn't work. `objLine` is passed by value to `getInstance` , it isn't modified and therefore `delete objLine` will actually be a call to `delete NULL`, which results in a no op. – Stefano Sanfilippo Jun 08 '15 at 11:19
2

The scope rule is valid for automatic allocation (i.e. of local variables). Instead, you are dynamically allocating instances of Line using the new operator:

void Line::getInstance(Line* objLine)
{
    if(objLine == NULL)
    {
        objLine = new Line();
    }
}

A dynamically allocated object is not bound to a scope and must be explicitely deleted using delete operator. Furthermore, the method above is leaking memory: once you leave the function, you will have lost any reference to the newly created object and therefore you will have no way to access or delete it. You'll want to actually modify the pointer you are passed, e.g. by modifying your code as follows:

void Line::getInstance(Line** objLine)
{
    if(objLine == NULL)
    {
        *objLine = new Line();
    }
}

at this point you can use it like:

int main()
{
    Line* objLine = NULL;
    Line::getInstance(&objLine);
    // do something...
    delete objLine;
    return 0;
}
Stefano Sanfilippo
  • 32,265
  • 7
  • 79
  • 80
  • 1
    `The scope rule is valid for static allocation` Actually, statically allocated objects are not destroyed at the end of scope. They're destroyed after `main` returns. You probably meant automatic (stack) allocation. – eerorika Jun 08 '15 at 11:33
  • 1
    @user2079303 I meant _static_ (as in compile-time) as opposed to _dynamic_ (as in runtime), but yes, _automatic_ is more correct and I've edited the post accordingly. I though that _"automatic storage"_ might sound a bit strange to a newcomer. – Stefano Sanfilippo Jun 08 '15 at 11:36