特殊的函数:析构函数

作者:jicanmeng

时间:2014年11月25日


与类的构造函数相对应的是类的析构函数。它是c++类中另一个特殊的成员函数,函数名称是在类名称前加一个"~"符号(逻辑非),表示和构造函数的功能相反。

当对象的生存期结束后,或者使用delete释放由new分配的动态内存的对象时,析构函数会被自动调用。

对于析构函数,需要注意的地方有:

  1. 每一个类最多只能有一个析构函数,且应为public型,否则类实例化后无法自动调用析构函数进行释放,但它不能重载,没有任何参数,也不返回任何值,其函数名前也不能有任何关键字(包括void)。
  2. 与类的其它成员函数一样,析构函数的定义也可以在类外进行,但必须指明它所属的类,且在类体中还必须要有析构函数的声明。
  3. 与默认构造函数类似,若类的声明中没有定义析构函数,则编译时会自动生成一个隐式的不进行任何操作的默认析构函数。

看一个示例程序:

#include <iostream>
#include <cstring>
using namespace std;

class MyString
{
private:
    char *m_pchString;
    int m_nLength;

public:
    MyString(const char *pchString="")
    {
        // Find the length of the string
        // Plus one character for a terminator
        m_nLength = strlen(pchString) + 1;

        m_pchString = new char[m_nLength];
        strncpy(m_pchString, pchString, m_nLength);

        // Make sure the string is terminated
        m_pchString[m_nLength-1] = '\0';
        cout << "MyString constructor called" << endl;
    }

    ~MyString() // destructor
    {
        // We need to deallocate our buffer
        if(m_pchString){
            cout << "MyString destructor called. m_pchString is " << m_pchString << endl;
            delete[] m_pchString;
            m_pchString = NULL;
        }
    }

    char* GetString() { return m_pchString; }
    int GetLength() { return m_nLength; }
};

int main()
{
    MyString NameOne("Alex");
    cout << "My name is: " << NameOne.GetString() << endl;

    // Allocate a MyString dynamically
    MyString *pNameTwo = new MyString("Lilei");
    cout << "My name is: " << pNameTwo->GetString() << endl;
    delete pNameTwo;

    {
        MyString NameThree("HanMeimei");
        cout << "My name is: " << NameThree.GetString() << endl;
    }

    cout << "program would exit!" << endl;
    return 0;
} // NameOne destructor called here!

看一看运行结果:

[jicanmeng@andy tmp]$ g++ destructor.cpp
			[jicanmeng@andy tmp]$ ./a.out
			MyString constructor called
			My name is: Alex
			MyString constructor called
			My name is: Lilei
			MyString destructor called. m_pchString is Lilei
			MyString constructor called
			My name is: HanMeimei
			MyString destructor called. m_pchString is HanMeimei
			program would exit!
			MyString destructor called. m_pchString is Alex
			[jicanmeng@andy tmp]$

对上面的程序简单分析一下:上面的程序创建了三个MyString类型的对象。前面提到,当对象的生存期结束后,或者使用delete释放由new分配的动态内存的对象时,析构函数会被自动调用。NameOne对象在程序结束时生存期结束了才会销毁。而pNameTwo指向的对象是使用delete来销毁的。NameThree在一个单独的block中,它的作用域只限于这个block,出了这个block,这个对象的生存期结束,所以也销毁了。

参考资料

  1. <<C++实用教程>> 电子工业出版社 郑阿奇 主编 丁有和 编著
  2. The C++ Tutorial:
    http://www.learncpp.com/cpp-tutorial/86-destructors/
    http://www.learncpp.com/cpp-tutorial/41-blocks-compound-statements-and-local-variables/