您的位置:首页 > 编程语言 > C语言/C++

Effective c++ 条款14: 确定基类有虚析构函数

2014-07-18 17:09 375 查看
/*

c++语言标准关于这个问题的阐述非常清楚:当通过基类的指针去删除派生类的对象,而基类又没有虚析构函数时,结果将是不可确定的。

这意味着编译器生成的代码将会做任何它喜欢的事:重新格式化你的硬盘,给你的老板发电子邮件,把你的程序源代码传真给你的对手,

无论什么事都可能发生。(实际运行时经常发生的是,派生类的析构函数永远不会被调用。在本例中,这意味着当targetptr 删除时,

enemytank的数量值不会改变,那么,敌人坦克的数量就是错的,这对需要高度依赖精确信息的部队来说,会造成什么后果?)

为了避免这个问题,只需要使基类的析构函数为virtual。声明析构函数为虚就会带来你所希望的运行良好的行为:对象内存释放时,

基类和派生类的析构函数都会被调用。 

实际上,很多人这样总结:当且仅当类里包含至少一个虚函数的时候才去声明虚析构函数。
*/

#ifndef PERSON_H
#define PERSON_H

#include <iostream>

class Person
{
public:
int ID;
public:
Person();
Person(int id);
virtual ~Person(); /// 如果基类的析构函数不是虚函数,那么用基类指针释放派生类的时候,不会调用派生类的析构函数。
/// 可以把virtual关键字注释然后查看输出和不注释virtual关键字输出的不同。
virtual int get_num(){return num;}

static int num;
};

#endif

class Child : public Person
{
public:
Child(){num++;}
virtual ~Child(){num--;}

virtual int get_num(){return num;}
private:
static int num;
};

class Adult : public Person
{
public:
Adult(){num++;}
virtual ~Adult(){num--;}

virtual int get_num(){return num;}
private:
static int num;
};

#include "vld.h"
#include "vldapi.h"
#include "person.h"
#include <iostream>

using namespace std;
int main()
{
Person* p=new Person();
Child c;
Adult a;

Person* child =new Child();
cout<<child->get_num()<<endl;

Person* adult = new Adult();

cout<<adult->get_num()<<endl;

cout<<p->get_num()<<endl;

delete child;

cout<<c.get_num()<<endl;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: