C++的虚拟析构


我们知道构造函数的顺序是:
1.基类构造函数(基类子对象的成员里如果有类类型的成员,先调用类类型成员的构造函数,再调用基类的构造函数)
2.派生类的类类型成员的构造函数
3.派生类的构造函数
对于多继承:基类构造函数被调用的顺序以类派生表中声明的顺序为准
如class Panda:public Bear,public Endangered{};
先构造Bear,再构造Endangered,再构造Panda;
析构的顺序和构造的相反;
考虑下面的例子
Example 1:
class C{
      public:
      C(){cout<<"This is C Constructor"<<endl;}
       ~C(){cout<<"This is C Destructor"<<endl;}
      };
class A{
public:
       A(){
           cout<<"This is A Constructor"<<endl;
          }
       // void print(int a){cout<<"This is C Des"<<a<<endl;}


       C c;
        ~A(){
           cout<<"This is A Destructor"<<endl;
          }
};
class B: public A,public C{
public:
       B(){cout<<"This is B Constructor"<<endl;}
        ~B(){cout<<"This is B Destructor"<<endl;}
};
int main()
{
  A *a=new B;
   delete a;
    system("PAUSE");
    return EXIT_SUCCESS;
}

 

输出:
This is C Constructor
This is A Constructor
This is C Constructor
This is B Constructor
This is A Destructor
This is C Destructor
没有完全被析出来
##########################################################################################
Example 2:
class C{
      public:
      C(){cout<<"This is C Constructor"<<endl;}
       ~C(){cout<<"This is C Destructor"<<endl;}
      };
class A{
public:
       A(){
           cout<<"This is A Constructor"<<endl;
          }
       // void print(int a){cout<<"This is C Des"<<a<<endl;}


       C c;
       virtual ~A(){
           cout<<"This is A Destructor"<<endl;
          }//多了个virtual

};
class B: public A,public C{
public:
       B(){cout<<"This is B Constructor"<<endl;}
        ~B(){cout<<"This is B Destructor"<<endl;}
};
int main()
{
  A *a=new B;
   delete a;
    system("PAUSE");
    return EXIT_SUCCESS;
}
 


输出:
This is C Constructor
This is A Constructor
This is C Constructor
This is B Constructor
This is B Destructor
This is C Destructor
This is A Destructor
This is C Destructor
完全被析出来了~
Example 3:
class C{
      public:
      C(){cout<<"This is C Constructor"<<endl;}
       ~C(){cout<<"This is C Destructor"<<endl;}
      };
class A{
public:
       A(){
           cout<<"This is A Constructor"<<endl;
          }
       // void print(int a){cout<<"This is C Des"<<a<<endl;}


       C c;
        ~A(){
           cout<<"This is A Destructor"<<endl;
          }
};
class B: public A,public C{
public:
       B(){cout<<"This is B Constructor"<<endl;}
        ~B(){cout<<"This is B Destructor"<<endl;}

      // virtual  ~B(){cout<<"This is B Destructor"<<endl;}也可 结果一样

};
int main()
{
  B *a=new B;
   delete a;
    system("PAUSE");
    return EXIT_SUCCESS;
}
 


输出:
This is C Constructor
This is A Constructor
This is C Constructor
This is B Constructor
This is B Destructor
This is C Destructor
This is A Destructor
This is C Destructor
这个是很自然的,因为
B *a=new B;
delete a;
Example 4:class C{
      public:
      C(){cout<<"This is C Constructor"<<endl;}
      virtual ~C(){cout<<"This is C Destructor"<<endl;}
      };
class A{
public:
       A(){
           cout<<"This is A Constructor"<<endl;
          }
       // void print(int a){cout<<"This is C Des"<<a<<endl;}


       C c;
       virtual ~A(){
           cout<<"This is A Destructor"<<endl;
          }
};
class B: public A,public C{
public:
       B(){cout<<"This is B Constructor"<<endl;}
        ~B(){cout<<"This is B Destructor"<<endl;}
};
int main()
{
  C*a=new B;
   delete a;
    system("PAUSE");
    return EXIT_SUCCESS;
}

 


结果同Example 2:
This is C Constructor
This is A Constructor
This is C Constructor
This is B Constructor
This is B Destructor
This is C Destructor
This is A Destructor
This is C Destructor

小结论:
一般规则 将根基类的析构函数声明为虚拟的,这样就能将所有的基类子对象释放

要不然就想第一个一样,没完全释放!

相关内容