Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
C++ For Dummies (2004) [eng].pdf
Скачиваний:
84
Добавлен:
16.08.2013
Размер:
8.09 Mб
Скачать

Chapter 16: “Why Do You Build Me Up, Just to Tear Me Down, Baby?” 217

Dissecting a Destructor

Just as objects are created, so are they destroyed (ashes to ashes, dust to dust). If a class can have a constructor to set things up, it should also have a special member function to take the object apart. This member is called the destructor.

Why you need the destructor

A class may allocate resources in the constructor; these resources need to be deallocated before the object ceases to exist. For example, if the constructor opens a file, the file needs to be closed before leaving that class or the pro­ gram. Or, if the constructor allocates memory from the heap, this memory must be freed before the object goes away. The destructor allows the class to do these cleanup tasks automatically without relying on the application to call the proper member functions.

Working with destructors

The destructor member has the same name as the class, but with a tilde (~) added at the front. (C++ is being cute again — the tilde is the symbol for the logical NOT operator. Get it? A destructor is a “not constructor.” Très clever.) Like a constructor, the destructor has no return type. For example, the class Student with a destructor added appears as follows:

class Student

{

public:

Student()

{

semesterHours = 0; gpa = 0.0;

}

~Student()

{

// ...whatever assets are returned here...

}

protected:

int semesterHours; float gpa;

};

218 Part III: Introduction to Classes

The destructor is invoked automatically when an object is destroyed, or in C++ parlance, when an object is destructed. That sounds sort of circular (“the destructor is invoked when an object is destructed”), so I’ve avoided the term until now. For non-heap memory, you can also say, “when the object goes out of scope.” A local object goes out of scope when the function returns. A global or static object goes out of scope when the program terminates.

But what about heap memory? A pointer may go out of scope, but heap memory doesn’t. By definition, it’s memory that is not part of a given function. An object that has been allocated off the heap is destructed when it’s returned to the heap using the delete command. This is demonstrated in the following DestructMembers program:

//

//DestructMembers - this program both constructs and

//

destructs a set of data members

//

 

#include <cstdio>

 

#include <cstdlib>

 

#include <iostream>

 

using namespace std;

 

class Course

{

public:

Course() { cout << “constructing course” << endl; } ~Course() { cout << “destructing course” << endl; }

};

class Student

{

public:

Student()

{

cout << “constructing student” << endl; semesterHours = 0;

gpa = 0.0;

}

~Student() { cout << “destructing student” << endl; } protected:

int semesterHours; float gpa;

};

class Teacher

{

public:

Teacher()

{

cout << “constructing teacher” << endl; pC = new Course;

Chapter 16: “Why Do You Build Me Up, Just to Tear Me Down, Baby?” 219

}

~Teacher()

{

cout << “ destructing teacher” << endl; delete pC;

}

protected: Course* pC;

};

class TutorPair

{

public:

TutorPair()

{

cout << “constructing tutorpair” << endl; noMeetings = 0;

}

~TutorPair() { cout << “ destructing tutorpair” << endl;

}

protected: Student student; Teacher teacher;

int noMeetings;

};

TutorPair* fn()

{

cout << “Creating TutorPair object in function fn()” << endl;

TutorPair tp;

cout << “Allocating TutorPair off the heap” << endl; TutorPair* pTP = new TutorPair;

cout << “Returning from fn()” << endl; return pTP;

}

int main(int nNumberofArgs, char* pszArgs[])

{

//call function fn() and then return the

//TutorPair object returned to the heap TutorPair* pTPReturned = fn();

cout << “Return heap object to the heap” << endl; delete pTPReturned;

//wait until user is ready before terminating program

//to allow the user to see the program results system(“PAUSE”);

return 0;

}

220 Part III: Introduction to Classes

The function main() invokes a function fn() that defines the object tp — this is to allow you to watch the variable go out of scope when control exits the function. fn() also allocates heap memory that it returns to main() where the memory is returned to the heap.

If you execute this program, it generates the following output:

Creating TutorPair object in function fn() constructing student

constructing teacher constructing course constructing tutorpair

Allocating TutorPair off the heap constructing student constructing teacher constructing course

constructing tutorpair Returning from fn() destructing tutorpair destructing teacher destructing course destructing student

Return heap object to the heap destructing tutorpair destructing teacher destructing course destructing student

Press any key to continue . . .

Each constructor is called in turn as the TutorPair object is built up, start­ ing from the smallest data member and working its way up to the TutorPair ::TutorPair() constructor function.

Two TutorPair objects are created. The first, tp, is defined locally to the function fn(), the second, pTP, is allocated off the heap. tp goes out of scope and is destructed when control passes out of the function. The heap memory whose address is returned from fn() is not destructed until main() deletes it.

The sequence of destructors invoked when an object is destructed is invoked in the reverse order in which the constructors were called.