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;
};
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; }
相关文章推荐
- Effective C++ 条款14: 确定基类有虚析构函数
- [Effective C++]条款14: 确定基类有虚析构函数
- 条款 14: 确定基类有虚析构函数
- 条款14: 确定基类有虚析构函数
- effective C++笔记之条款14:确定基类有虚析构函数
- effective c++ 条款7,8(为多态基类声明virtual析构函数,别让异常逃离析构函数)
- Effective C++学习笔记:确定基类有虚析构函数
- 条款14 基类的析构函数一定要定义为虚拟函数(From Effective C++)
- Effective C++ 条款07 为多态基类声明virtual 析构函数
- Effective C++学习笔记:确定基类有虚析构函数
- 14 确定基类有虚析构函数(exercised)
- Effective C++学习笔记:确定基类有虚析构函数
- Effective C++ 条款07 为多态基类声明virtual 析构函数
- 确定基类有虚析构函数
- Effective C++ 条款08 别让异常逃离析构函数
- Effective C++ 条款八 别让异常逃离析构函数
- 条款 07 为多态基类声明vitual析构函数
- effective C++ 条款 32:确定你的public继承塑模出is-a
- 《Effective C++》之条款32:确定你的public继承塑模出is-a关系
- 《Effective C++》:条款43:学习处理模板化基类内的名称