8.1.3 析构函数与动态内存分配(2)
CMessage类析构函数的代码如下所示:
- // Listing 08_02_2
- // Destructor to free memory allocated by new
- CMessage::~CMessage()
- {
- cout << "Destructor called." // Just to track what happens
- << endl;
- delete[] pmessage; // Free memory assigned to pointer
- }
因为是在类定义外部定义析构函数,所以必须以类名CMessage限定析构函数名。析构函数的作用只是显示一条消息,告诉我们所发生的事情,然后使用delete操作符释放pmessage成员指向的内存。注意,delete后面的方括号是必需的,因为我们是在删除数组(char类型)。
试一试:使用消息类
通过下面这个小示例,可以练习CMessage类的用法。
- // Ex8_02.cpp
- // Using a destructor to free memory
- #include <iostream> // For stream I/O
- #include <cstring> // For strlen() and strcpy()
- using std::cout;
- using std::endl;
- // Put the CMessage class definition here (Listing 08_02_1)
- // Put the destructor definition here (Listing 08_02_2)
- int main()
- {
- // Declare object
- CMessage motto("A miss is as good as a mile.");
- // Dynamic object
- CMessage* pM(new CMessage("A cat can look at a queen."));
- motto.ShowIt(); // Display 1st message
- pM->ShowIt(); // Display 2nd message
- cout << endl;
- delete pM; // Manually delete object created with new
- return 0;
- }
记着用上一节的CMessage类和析构函数定义的代码代替此处代码中的注释,如果没有它们,那么将不能编译该程序(下载的源代码中含有本示例的所有代码)。
示例说明
在main()的开始部分,以通常的方式声明并定义了一个已初始化的CMessage对象motto。在第二条声明语句中,定义了一个指向CMessage对象的指针pM,并使用new操作符为该指针指向的CMessage对象分配内存。对new操作符的调用将调用CMessage类的构造函数,结果是再次调用new操作符为数据成员pmessage指向的消息文本分配空间。如果构建并执行该示例,那么将得到下面的输出:
- A miss is as good as a mile.
- A cat can look at a queen.
- Destructor called.
- Destructor called.
输出中记录了两次析构函数调用,用于两个CMessage对象。如前所述,编译器不负责删除在空闲存储器中创建的对象。编译器之所以为对象motto调用析构函数,是因为虽然该对象的数据成员占用的内存是由构造函数在空闲存储器中分配的,但它只是一个普通的自动对象。pM指向的对象就不同了。在空闲存储器中为该对象分配内存,因此必须使用delete将其删除。使下面这条出现在main()中return语句之前的语句是注释形式:
- // delete pM; // Manually delete object created with new
如果现在运行该程序,则得到下面的输出:
- A miss is as good as a mile.
- A cat can look at a queen.
- Destructor called.
现在,只调用了一次析构函数,这有些令人惊奇。显然,delete只处理main()函数中new操作符分配的内存,即只释放指针pM指向的内存。因为指针pM指向一个CMessage对象(该类的析构函数已经定义过),所以delete操作符还要调用析构函数来释放该对象的成员所占用的内存。因此,当使用delete操作符删除动态创建的对象时,delete操作符将在释放该对象占用的内存之前,首先调用该对象的析构函数。这可以确保也释放为类成员动态分配的任何内存。