0

I have created a class, and according to the textbook Accelerated C++ by Andrew Koenig and Barbara E. Moo,

The work of the destructor is to do any cleanup that should be done whenever an object goes away. Typically this cleanup involves releasing resources, such as memory, that the constructor has allocated.

I am trying to write a destructor, and I'm getting confused by all the code floating out there. Sometimes a simple deconstructor like this is used ~MyIntArray() {} and sometimes there are things between the {}.

What is the rule behind putting things between the curly brackets or not? Is it just containers e.g. lists, arrays, vectors, pointers that need to be placed between the curly brackets (these are the things I see in code examples out there).

edit: this is my class in case that's needed

class msgInfo
{
public:
    msgInfo();
    msgInfo(int, int, int, std::string, std::list<int>);

private:
    int source_id;
    int dest_id;
    int priority;
    std::string payload;
    std::list<int> nodePath;
};
sccs
  • 1,123
  • 3
  • 14
  • 27
  • possible duplicate of [Practical application of class destructor C++](http://stackoverflow.com/questions/10310513/practical-application-of-class-destructor-c) – Bo Persson Mar 27 '13 at 07:38
  • 1
    From your list of four (lists, arrays, vectors and pointers) pointers are the only one that needs handling in the destructor. Your class doesn't have any of those so doesn't need a destructor. This is a good thing, and what I would expect from someone reading Koenig and Moo. – john Mar 27 '13 at 08:16

8 Answers8

3

Rule 1:

Rule of three in C++03 or rule of five in C++11.

If your class needs a user defined copy constructor or a copy assignment operator then it most likely needs a user defined destructor.

When do you need either of these 3?

  • When your class has dynamically allocated pointer members and you need to maintain lifetime of each separate from that of another instance member. For e.g: char * member.
  • When you manage resources. For e.g: Open file handles, mutex locks etc.

Rule 2:

If your class is intended to be used for derivation and you need polymorphic deletion of objects then you must mark the destructor in Base class as virtual.

Community
  • 1
  • 1
Alok Save
  • 202,538
  • 53
  • 430
  • 533
2

Well, if you allocated resources dynamically (new etc..) then in the destructor you'd want to release them (delete), in your case, since all of your members are not allocated dynamically, your destructor can be empty ( or non existent).

Another note worth mentioning is, if you do end up implementing the destructor, and you plan on someone inherting your class, you should make it virtual.

Alon
  • 1,776
  • 13
  • 31
  • If you don't explicitly provide a destructor, a standard destructor will be provided by the compiler, so it is there anyways. – bash.d Mar 27 '13 at 07:41
  • You should only make the destructor virtual if you intend the class to be derived from, in which case you should do so anyway. Saying that you should always declare it virtual is bad advice. – juanchopanza Mar 27 '13 at 07:43
  • if your destructor is private, how can it be deleted from the one who allocates it? – Alon Mar 27 '13 at 07:44
  • As for making the destructor virtual, there is a risk pointed out here(http://www.cprogramming.com/tutorial/constructor_destructor_ordering.html) – CuriousSid Mar 27 '13 at 07:45
  • @Alon - could be "deleted" from a friend class, for example - when you implement an intrusive reference counting smart pointer. – Kiril Kirov Mar 27 '13 at 07:45
  • @Alon No, it does exist, you just don't provide any, that's the reason. – bash.d Mar 27 '13 at 07:45
  • Sorry, I meant "virtual", not "public". But you fixed that already :-) – juanchopanza Mar 27 '13 at 07:47
1

It is a good programming practice to provide a destructor in your C++ program even if there is no explicit need for one. In your code you might not have any dynamic memory allocation, so the destructor provided is simply ~MyIntArray() {} without any code inside.

Please also read the Wikipedia article on Rule of Three in C++.

http://en.wikipedia.org/wiki/Rule_of_three_(C%2B%2B_programming)

Deepu
  • 7,592
  • 4
  • 25
  • 47
1

Your class does not have any resources that need to be dealt with in the destructor: each type is either built-in (`int) or handles its own resources (std::string,std::list`). So you do not need to implement your own destructor. The compiler will provide one that is equivalent to the empty braces one.

You would need to implement your own if your class had resources that need dealing with: dynamically allocated objects, handles or connections to sockets, databases, reference counts, etc.

One situation where it might make sense to implement an empty destructor is when you have a class which is intended to be derived from and used polymorphically. In this case, a virtual destructor is needed (there are many SO posts about that), and it is common practice to provide an empty implementation so that derived types to not have to implement it themselves when there are no resources to deal with.

virtual ~Foo() {}
juanchopanza
  • 223,364
  • 34
  • 402
  • 480
1

If you don't provide a destructor, the compiler will provide one for you. This automatically-generator destructor will correctly call the destructors of all of your class's data members, such as payload etc.

If you don't need to do anything beyond that then you don't need to explicitly provide a destructor. Alternatively, an empty one would work equally well.

If, on the other hand, your constructor allocates some resources (for example, connects to a database), then typically you'd need to put some code in your destructor to release that resource (e.g. disconnect from the database). This is the standard C++ idiom used to prevent resource leaks.

NPE
  • 486,780
  • 108
  • 951
  • 1,012
0

A class like this doesn't need a non-trivial destructor (one, with "things between the curly brackets").

In a destructor, you must release resources, you have "manually" allocated. For example:

  • if you have new/new[] in the constructor and you need to free this memory in the destructor
  • if you have opened a file in the constructor, close it in the destructor
  • if you have locked a mutex in the constructor, unlock it in the destructor

Things like this.

Also, you may need some additional logic to be implemented, when an object is being destructed. Depends on what you're trying to do.

Kiril Kirov
  • 37,467
  • 22
  • 115
  • 187
0

A definition of a destructor should, as far as I know or am concerned, should always look like this:

~msgInfo() { /* free stuff */ }

A constructor on the other hand may look like this:

msgInfo(): m_var1(0), m_var2("Initialize") { /* further initialization */ }

Where what comes between : and { is member variable initialization.

In the destructor you should deallocate anything which was dynamically allocated elsewhere in the class, hence the : notation is no good, since you probably need to do delete on the objects.

fredrik
  • 6,483
  • 3
  • 35
  • 45
  • the OP hasn't mentioned anything about initialization lists. The question here seems only to be *What is the rule behind putting things between the curly brackets or not?* - no mentioned of `:`. – default Mar 27 '13 at 07:46
0

In your code you might not have any dynamic memory allocation,so you don't need to provide a destructor.

premierlee
  • 11
  • 1