析构函数

一个析构函数是无时,用户定义的对象将要被销毁的被称为自变量的函数。它以~前缀破坏的类型命名。

class C{
    int* is;
    string s;
public:
    C()
    : is( new int[10] ){
    }

    ~C(){  // destructor definition
        delete[] is;
    }
};

class C_child : public C{
    string s_ch;
public:
    C_child(){}
    ~C_child(){} // child destructor
};

void f(){
    C c1; // calls default constructor
    C c2[2]; // calls default constructor for both elements
    C* c3 = new C[2]; // calls default constructor for both array elements

    C_child c_ch;  // when destructed calls destructor of s_ch and of C base (and in turn s)

    delete[] c3; // calls destructors on c3[0] and c3[1]
} // automatic variables are destroyed here -- i.e. c1, c2 and c_ch

在大多数情况下(即,用户不提供析构函数,并且没有其他不合格条件),编译器会隐式提供默认析构函数:

class C{
    int i;
    string s;
};

void f(){
    C* c1 = new C;
    delete c1; // C has a destructor
}
class C{
    int m;
private:
    ~C(){} // not public destructor!
};

class C_container{
    C c;
};

void f(){
    C_container* c_cont = new C_container;
    delete c_cont; // Compile ERROR: C has no accessible destructor
}

Version > C++ 11

在 C++ 11 中,开发人员可以通过阻止编译器提供默认析构函数来覆盖此行为。

class C{
    int m;
public:
    ~C() = delete; // does NOT have implicit destructor
};

void f{
    C c1; 
} // Compile ERROR: C has no destructor

此外,开发人员也可能明确要求编译器提供默认的析构函数。

class C{
    int m;
public:
    ~C() = default; // saying explicitly it does have implicit/empty destructor
};

void f(){
    C c1;
} // C has a destructor -- c1 properly destroyed

Version > C++ 11

你可以使用 <type_traits> 中的 std::is_destructible 来确定类型是否具有析构函数(或者是基本类型):

class C1{ };
class C2{ public: ~C2() = delete };
class C3 : public C2{ };

using std::cout; using std::boolalpha; using std::endl;
using std::is_destructible;
cout << boolalpha << is_destructible<int>() << endl; // prints true
cout << boolalpha << is_destructible<C1>() << endl; // prints true
cout << boolalpha << is_destructible<C2>() << endl; // prints false
cout << boolalpha << is_destructible<C3>() << endl; // prints false