C++的虚拟析构
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
小结论:
一般规则 将根基类的析构函数声明为虚拟的,这样就能将所有的基类子对象释放
要不然就想第一个一样,没完全释放!
评论暂时关闭