您的位置:首页 > 其它

析构函数声明为虚函数的情况

2016-04-12 17:36 246 查看
转自:http://www.cnblogs.com/children/archive/2012/08/13/2636956.html

先看下面一段程序:

#include <iostream>

using namespace std;

class Person

{

public:

virtual ~Person()                    //加了virtual,讲析构函数声明为虚函数

{

   cout << "Person::~Person()" << endl;

}

};

class Student : public Person

{

public:

~Student()                                 // virtual可加可不加

{

   cout << "Student::~Student()" << endl;

}

};

int main()

{

Person *pt1 = new Person;

Person *pt2 = new Student;          // 用基类的指针指向子类

// Student *pt3 = new Person;     // 不能用子类指针指向基类,错误!

Student *pt4 = new Student;

delete pt1;

cout << "*********" << endl;

delete pt2;

cout << "*********" << endl;

//delete pt3;

//cout << "*********" << endl;

delete pt4;

cout << "*********" << endl;

return 0;

}

 

运行结果:

Person::~Person()

***********

Student::~Student()

Person::~Person()

**********

Student::~Student()

Person::~Person()

**********

 

如果在基类中析构函数不加virtual,结果为:

Person::~Person()

***********

Person::~Person()

**********

Student::~Student()

Person::~Person()

**********

只有在基类的指针指向派生类的时候,才会出现这种情况,虚函数起到了动态的作用。

析构函数执行时先调用派生类的析构函数,再调用派生类的析构函数,如果基类的析构函数不是虚函数,又要通过基类的指针去销毁指向派生类的动态对象,那么在调用delete销毁对象时,只调用了基类的析构函数,没有调用派生类的析构函数,导致销毁对象不完全。

如果在上面的例子中,基类中未定义virtual析构函数,而派生类中定义了virtual的析构函数,此时用基类指针指向派生类,再delete掉,

即:

class Person

{

public:

~Person()                    

{

   cout << "Person::~Person()" << endl;

}

};

class Student : public Person

{

public:

virtual ~Student()                                

{

   cout << "Student::~Student()" << endl;

}

};

 

Person * pt = new Student;

delete pt;

运行结果会出错。

反正是只要基类析构没有定义为virtual,而派生类(可能有多层)中有把析构定义为virtual的,此时用基类的指针指向派生类,再delete,会出错。

而:

class Person

{

public:

~Person()

{

   cout << "Person::~Person()" << endl;

}

};

class Student : public Person

{

public:

virtual ~Student()

{

   cout << "Student::~Student()" << endl;

}

};

class OneSt : public Student

{

public:

~OneSt()

{

   cout << "OneSt::~OneSt()" << endl;

}

};

 

如果用

Student * pt = OneSt;  

delete pt;

运行结果为:

OneSt::~OneSt()

Student::~Student()

Person::~Person()

是可以运行的。

 

Effective C++ (第7条:要将多态基类的析构函数声明为虚函数)

需要记住的
应该为多态基类声明虚析构器。一旦一个类包含虚函数,它就应该包含一个虚析构器。
如果一个类不用作基类或者不需具有多态性,便不应该为它声明虚析构器。

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息