8.1.2 默认的析构函数
我们迄今使用过的所有对象都是被类的默认析构函数自动销毁的。如果我们不自行定义析构函数,编译器就总是生成默认的析构函数。默认的析构函数不能删除new运算符在自由存储器中分配的对象或对象成员。如果类成员占用的空间是在构造函数中动态分配的,我们就必须自定义析构函数,然后显式使用delete运算符来释放构造函数使用new运算符分配的内存,就像销毁普通变量一样。我们需要在编写析构函数方面实践一下,因此下面就来试一试。
试一试:简单的析构函数
为了解何时调用类的析构函数,我们可以在CBox类中添加析构函数。下面是本示例的代码,其中包括的CBox类有一个析构函数:
- // Ex8_01.cpp
- // Class with an explicit destructor
- #include <iostream>
- using std::cout;
- using std::endl;
-
- class CBox
// Class definition at global scope - {
- public:
- // Destructor definition
- ~CBox()
- {
- cout << "Destructor called." << endl;
- }
-
- // Constructor definition
- CBox(double lv = 1.0, double wv = 1.0, double hv = 1.0):
- m_Length(lv), m_Width(wv), m_Height(hv)
- {
- cout << endl << "Constructor called.";
- }
-
- // Function to calculate the volume of a box
- double Volume() const
- {
- return m_Length*m_Width*m_Height;
- }
-
- // Function to compare two boxes which returns true
- // if the first is greater that the second, and false otherwise
- int compare(CBox* pBox) const
- {
- return this->Volume() > pBox->Volume();
- }
- private:
- double m_Length;
// Length of a box in inches - double m_Width;
// Width of a box in inches - double m_Height;
// Height of a box in inches - };
-
- // Function to demonstrate the CBox class destructor in action
- int main()
- {
- CBox boxes[5];
// Array of CBox objects declared - CBox cigar(8.0, 5.0, 1.0); // Declare cigar box
- CBox match(2.2, 1.1, 0.5); // Declare match box
- CBox* pB1 = &cigar;
// Initialize pointer to cigar object address - CBox* pB2 = 0;
// Pointer to CBox initialized to null -
- cout << endl
- << "Volume of cigar is "
- << pB1->Volume();
// Volume of obj. pointed to -
- pB2 = boxes;
// Set to address of array - boxes[2] = match;
// Set 3rd element to match - cout << endl
- << "Volume of boxes[2] is "
- << (pB2 + 2)->Volume(); // Now access thru pointer
-
- cout << endl;
- return 0;
- }
示例说明
CBox类的析构函数仅仅显示一条宣称"析构函数被调用"的消息。该示例的输出如下:
- Constructor called.
- Constructor called.
- Constructor called.
- Constructor called.
- Constructor called.
- Constructor called.
- Constructor called.
- Volume of cigar is 40
- Volume of boxes[2] is 1.21
- Destructor called.
- Destructor called.
- Destructor called.
- Destructor called.
- Destructor called.
- Destructor called.
- Destructor called.
在程序结束时,每个对象都需要调用一次析构函数。每出现一次构造函数的调用,就有一次匹配的析构函数调用。在这里,我们不需要显式调用析构函数。当某个类对象无效时,编译器将自动安排调用该类的析构函数。本示例中,析构函数的调用发生在main()函数的执行结束之后,因此在main()函数安全终止之后因析构函数存在错误而使程序崩溃也是非常有可能的。