《深度探索C++对象模型》P.233 L.-2:
一个由程序员定义的 destructor 被扩展的方式类似 constructor 被扩展的方式,但顺序相反:
1. 如果 object 内带一个 vptr,那么首先重设 (reset) 相关的 virtual table;
If the object contains a vptr, it is reset to the virtual table associated with the class.
2. destructor 的函数本身现在被执行,也就是说 vptr 会在程序员的码执行前被重设 (reset);
The body of the destructor is then executed; that is, the vptr is reset prior to evaluating the user-supplied code.
3. 如果 class 拥有 member class objects,而后者拥有 destructors,那么它们会以其声明顺序的相反顺序被调用;
If the class has member class objects with destructors, these are invoked in the reverse order of their declaration.
4. 如果有任何直接的(上一层)nonvirtual base classes 拥有 destructors,它们会以其声明顺序的相反顺序被调用;
If there are any immediate nonvirtual base classes with destructors, these are invoked in the reverse order of their declaration.
5. 如果有任何 virtual base classes 拥有 destructor,而当前讨论的这个 class 是最尾端 (most-derived) 的 class,那么它们会以其原来的构造顺序的相反顺序被调用。
If there are any virtual base classes with destructors and this class represents the most-derived class, these are invoked in the reverse order of their original construction.
侯捷认为正确的顺序应该是 2、3、1、4、5。即:
1. destructor 的函数本身首先被执行;
2. 如果 class 拥有 member class objects,而后者拥有 destructors,那么它们会以其声明顺序的相反顺序被调用;
3. 如果 object 内带一个 vptr,则现在被重新设定,指向适当之 base class 的 virtual table;
4. 如果有任何直接的(上一层)nonvirtual base classes 拥有 destructors,它们会以其声明顺序的相反顺序被调用;
5. 如果有任何 virtual base classes 拥有 destructor,而当前讨论的这个 class 是最尾端 (most-derived) 的 class,那么它们会以其原来的构造顺序的相反顺序被调用。
从下面测试代码的输出,可以看出,在 VC++ 2005 编译器中,侯捷的说法是正确的。
测试代码:
// VC++ 2005 #include <stdio.h> class Derived; Derived* g_pDerived = NULL; Derived* g_pDerived2 = NULL; class Base_Base { public: virtual ~Base_Base() { printf("/nBase_Base destructor/n"); vfunc(); } virtual void vfunc() { printf("Base_Base::vfunc/n"); } }; class Base: public virtual Base_Base { public: virtual ~Base() { printf("/nBase destructor/n"); vfunc(); } virtual void vfunc() { printf("Base::vfunc/n"); } }; class Base2_Base { public: virtual ~Base2_Base() { printf("/nBase2_Base destructor/n"); vfunc(); } virtual void vfunc() { printf("Base2_Base::vfunc/n"); } }; class Base2: public Base2_Base { public: virtual ~Base2() { printf("/nBase2 destructor/n"); vfunc(); } virtual void vfunc() { printf("Base2::vfunc/n"); } }; class Base3_Base { public: virtual ~Base3_Base() { printf("/nBase3_Base destructor/n"); vfunc(); } virtual void vfunc() { printf("Base3_Base::vfunc/n"); } }; class Base3: public Base3_Base { public: virtual ~Base3() { printf("/nBase3 destructor/n"); vfunc(); } virtual void vfunc() { printf("Base3::vfunc/n"); } }; class Base4_Base { public: virtual ~Base4_Base() { printf("/nBase4_Base destructor/n"); vfunc(); } virtual void vfunc() { printf("Base4_Base::vfunc/n"); } }; class Base4: virtual public Base4_Base { public: virtual ~Base4() { printf("/nBase4 destructor/n"); vfunc(); } virtual void vfunc() { printf("Base4::vfunc/n"); } }; class Base5_Base { public: virtual ~Base5_Base() { printf("/nBase5_Base destructor/n"); vfunc(); } virtual void vfunc() { printf("Base5_Base::vfunc/n"); } }; class Base5: virtual public Base5_Base { public: virtual ~Base5() { printf("/nBase5 destructor/n"); vfunc(); } virtual void vfunc() { printf("Base5::vfunc/n"); } }; class MemberClass { public: virtual ~MemberClass(); private: Derived* _pDerived; }; class MemberClass2 { public: virtual ~MemberClass2(); private: Derived* _pDerived; }; class Derived : virtual public Base , public Base2 , virtual public Base3 , virtual public Base5 , public Base4 { public: virtual ~Derived(); virtual void vfunc(); private: MemberClass mc; MemberClass2 mc2; }; Derived::~Derived() { printf("Derived destructor/n"); vfunc(); } void Derived::vfunc() { printf("Derived::vfunc/n"); } MemberClass::~MemberClass() { printf("/nMemberClass destructor/n"); _pDerived = new Derived; g_pDerived = _pDerived; _pDerived->vfunc(); } MemberClass2::~MemberClass2() { printf("/nMemberClass2 destructor/n"); _pDerived = new Derived; g_pDerived2 = _pDerived; _pDerived->vfunc(); } int main() { Derived oDerived; delete g_pDerived; delete g_pDerived2; return 0; }
程序输出:
Derived destructor Derived::vfunc MemberClass2 destructor Derived::vfunc MemberClass destructor Derived::vfunc Base4 destructor Base4::vfunc Base2 destructor Base2::vfunc Base2_Base destructor Base2_Base::vfunc Base4_Base destructor Base4_Base::vfunc Base5 destructor Base5::vfunc Base5_Base destructor Base5_Base::vfunc Base3 destructor Base3::vfunc Base3_Base destructor Base3_Base::vfunc Base destructor Base::vfunc Base_Base destructor Base_Base::vfunc