看了不少虚函数方面的文章,但对于虚析构函数在功能实现上还是不甚理解,于是决定实践一番,可让我收益匪浅啊
首先定义一个没有虚函数的基类:
#include<iostream> #include<string> using namespace std; class Sphere { public: Sphere(double initialRadius=0); double getRadius()const; void display()const;//not defined virtual function ~Sphere();//not defined virtual function private: double radius; }; class Ball:public Sphere { public: Ball(string initialname="",double initialRadius=0); void display()const; ~Ball(); private: string name; }; Sphere::Sphere(double initialRadius):radius(initialRadius) { } double Sphere::getRadius()const { return radius; } void Sphere::display()const { cout<<"the Radius is "<<radius<<endl; } Sphere::~Sphere() { cout<<"destructor Sphere object !"<<endl; } Ball::Ball(string initialname,double initialRadius) :Sphere(initialRadius),name(initialname) { } void Ball::display()const { cout<<"the name is "<<name<<endl; } Ball::~Ball() { cout<<"destructor Ball object !"<<endl; }
在main()函数下测试
#include"virtual.h" void test(Sphere &_sphere); int main() { Sphere *football=new Ball("football",15); test(*football); football->display(); delete football; return 0; } void test(Sphere &_sphere) { _sphere.display(); }
运行结果如下:
当基类中需要在派生类中重写(override)的函数没有声明为虚函数时(声明前加virtual),由基类类型定义的派生类对象没有调用与派生类相应的成员函数和析构函数。而是直接调用了基类的成员函数和析构函数。这当然不是我们所要的。
修改后的基类和派生类如下(添加了虚函数机制):
#include<iostream> #include<string> using namespace std; class Sphere { public: Sphere(double initialRadius=0); double getRadius()const; virtual void display()const;//defined virtual function virtual ~Sphere();//defined virtual function private: double radius; }; class Ball:public Sphere { public: Ball(string initialname="",double initialRadius=0); virtual void display()const;//virtual or not virtual ~Ball();//virtual or not private: string name; }; Sphere::Sphere(double initialRadius):radius(initialRadius) { } double Sphere::getRadius()const { return radius; } void Sphere::display()const { cout<<"the Radius is "<<radius<<endl; } Sphere::~Sphere() { cout<<"destructor Sphere object !"<<endl; } Ball::Ball(string initialname,double initialRadius) :Sphere(initialRadius),name(initialname) { } void Ball::display()const { cout<<"the name is "<<name<<endl; } Ball::~Ball() { cout<<"destructor Ball object !"<<endl; }
在main()函数下测试,结果如下图:
当对基类的成员函数和析构函数声明为虚函数时,是根据对象的实际类型来确定要执行的函数的。需要注意的是,当调用了派生类的析构函数时,自动调用了基类的析构函数。而基类的析构函数不为虚函数时,则有可能造成内存泄露。