destructors

Just wondering about the use of destructors.

Eg:
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
27
28
29
30

file: mainclass.h
class name
{
    public:
        name();
        ~name();
        int removeall();
...

};

file: classimplementation.cpp

#include "mainclass.h"

name::name()
{
...
}

name::~name()
{....}

int name::removeall()
{
    ~name();  just wondering why it doesn't work. is there anything i am missing?
    return 1;
}
 
you might want to change ~name(); to name::~name(); or this->~name(); at line 27
Last edited on
Thank you for the reply. It still doesn't work. any other ideas?

only works when i am outside the class, create class variable and do:
1
2
3
name data;

data.~name();


Thanks for editing . I think "this" worked.
Last edited on
The destructor will be called automatically when the object is destroyed. No need to call it explicitly.
it will be called automatically but it would be kind of a shortcut if one needs to remove all datas and keep the program running. I actually used it in some programs before but just couldn't remember how i used it.
If you created object using new, you can use delete to destroy it.
In other cases it will be called automaticlly, as Peter87 said.
The sensible thing to do is to have a method that performs whatever cleanup tasks you want to be able to do. Then the destructor can call that mthod, and your removeall method can also call it.
Invoking the destructor twice (one in the `removeall()' and later implicit when it goes out of scope)
results in undefined behaviour
I suppose he meant to have clear_all() method which both destructor and user function will call.
Yes. So not call destructor explicitly.
This whole set of FAQ might be more enlightening:
http://www.parashift.com/c++-faq/dont-call-dtor-on-local-really.html
Last edited on
Thank you for all the information. And Miniipaa, yes thats true but can i not make that function and just have all the things in destructor and just call destructor.

Actually i am not calling the destructor twice. But only trying it explicitly i guess. It does the garbage dump only when there is something to be destroyed. Simple eg:

1
2
3
4
5
Name::~name()
{
    If(head)
         .......
}


So since there is constructor, the destructor will be called once automatically but if i call it explicitly, then it wont be called again as there is nothing to be destroyed.
Destructor does more than you writing, and you can't change what it will do. Non-pointer data types, service information... So some memory areas will be freed twice, and imagine what happens if some other data was allocated here?
If your method: removeall() is supposed to have similar functionality to a destructor (as in it will free allocated memory), then in your case, I think it would be better to call removeall() from the destructor instead of vice versa.
1
2
3
4
5
6
7
8
9
10
name::~name()
{
    removeall();
}

int name::removeall()
{
    delete someMember;
    return 1;
}


This is similar to what happens in std::ifstream's constructor:
1
2
3
4
5
ifstream::ifstream(string filename)
{
    open(filename);
}
void ifstream::open(string filename) { ... }

The constructor and open have similar functionality. Instead of calling the constructor from open(), they call open() from the constructor. That will let us make use of the code reuse.

I actually commonly use this sort of thing when I making a controller that needs to be totally reset:
1
2
3
4
5
6
7
8
9
10
class PID
{
protected:
    init(); // Allocates memory
    exit(); // De-allocates memory
public:
    PID() { init(); }
    ~PID() { exit(); }
    Reset() { exit(); init(); }
};

The other advantage of putting your code inside of methods instead of constructors or destructors is that ctor/dtors are not inherited. If you want someone to inherit this functionality, then keep that code out of a constructor/destructor.

The only disadvantage that I see is that you can't make use of the initialization lists this way and you have to rely on assignments.

Edit: Thanks ne555
Last edited on
Well, they are initializated already.

By the way, your `Reset()' is backwards.
Thank You everyone. That really helped!
Topic archived. No new replies allowed.