一, 什么是虚函数?

简单地说,那些被virtual关键字修饰的成员函数,就是虚函数。虚函数的作用,用专业术语来解释就是实现多态性(Polymorphism),多态性是将接口与实现进行分离;用形象的语言来解释就是实现以共同的方法,但因个体差异而采用不同的策略。

所谓虚函数就是多态情况下只执行一个,而从继承的概念来讲,总是要先构造父类对象,然后才能是子类对象,如果构造函数设为虚函数,那么当你在构造父类的构造函数时就不得不显示的调用构造,还有一个原因就是为了防错,试想如果你在子类中一不小心重写了个跟父类构造函数一样的函数,那么你的父类的构造函数将被覆盖,也即不能完成父类的构造.就会出错.

析构函数在某些情况下必须为虚函数(比如你想让你类能够被继承,那么这个类的析构函数最好是虚的,继承一个析构函数不是虚的类是有风险的),值得补充的是,当基类的函数是虚函数,子类的重载的函数也是虚的,即使不加virtual关键字也是虚的。

如果子类覆盖的父类的虚函数
则父类的指针或引用实际指向子类的对象或指向自己的对象
那通过该指针或引用调用虚函数时,则将调用子类的(虚)函数 如果不是虚函数,则将调用父类的函数
class A{

public:

virtual void print(){ cout<<”This is A”<<endl;} //现在成了虚函数了

};

class B:public A{

public:

void print(){ cout<<”This is B”<<endl;} //这里需要在前面加上关键字virtual吗?

};

毫无疑问,class A的成员函数print()已经成了虚函数,那么class B的print()成了虚函数了吗?回答是Yes,我们只需在把基类的成员函数设为virtual,其派生类的相应的函数也会自动变为虚函数。所以,class B的print()也成了虚函数。那么对于在派生类的相应函数前是否需要用virtual关键字修饰,那就是你自己的问题了。

现在重新运行main2的代码,这样输出的结果就是This is A和This is B了。


int main(){ //main2

A a;

B b;

A* p1=&a;

A* p2=&b;

p1->print();

p2->print();

}

析构函数应定义为虚函数,否则容易发生内存泄露

1. 为什么构造函数不能为虚函数?

    虚函数的调用需要虚函数表指针,而该指针存放在对象的内容空间中;若构造函数声明为虚函数,那么由于对象还未创建,还没有内存空间,更没有虚函数表地址用来调用虚函数——构造函数了。
 
2. 为什么析构函数可以为虚函数,如果不设为虚函数可能会存在什么问题?
    首先析构函数可以为虚函数,而且当要使用基类指针或引用调用子类时,最好将基类的析构函数声明为虚函数,否则可以存在内存泄露的问题。
    举例说明:
    子类B继承自基类A;A *p = new B; delete p;
    1) 此时,如果类A的析构函数不是虚函数,那么delete p;将会仅仅调用A的析构函数,只释放了B对象中的A部分,而派生出的新的部分未释放掉。
    2) 如果类A的析构函数是虚函数,delete p; 将会先调用B的析构函数,再调用A的析构函数,释放B对象的所有空间。
    补充: B *p = new B; delete p;时也是先调用B的析构函数,再调用A的析构函数。
 
 

[from]

http://zhidao.baidu.com/question/32424351.html

http://www.cnblogs.com/zhice163/archive/2012/07/10/2584835.html

最新文章

  1. java观察者模式
  2. 阿里云系列——7.阿里云IIS系列详解(过程+通用+最新)
  3. Linux各个目录的作用及内容
  4. LCM 轻量级通信组件
  5. storm中DAU实时计算方案
  6. 托马斯微积分答案.djvu的书签
  7. php正则表达式治疗结巴
  8. js动态生成input指定My97DatePicker时间问题
  9. java获取点击微信自定义菜单的用户openid
  10. hdu 3032 Nim or not Nim? (SG函数博弈+打表找规律)
  11. 防止sql注入,过滤敏感关键字
  12. 高德地图 JavaScript API 开发系列教程(一)
  13. MAC安装SVNServer
  14. Eclipse无法识别(手机)设备的解决方案
  15. destoon框架二次开发【整理】
  16. 20175208 张家华 MyCP
  17. Maven(五)Eclipse配置Maven插件
  18. Java面试之高并发系统
  19. 8188EU 在AM335X MC183上以AP+STA工作
  20. centos搭建OPENldap

热门文章

  1. Linux-SSL和SSH和OpenSSH,OpenSSL有什么区别
  2. QQ登入(6)腾讯微博-获取微博用户信息,发送微博
  3. 检测php网站是否已经被攻破
  4. EF Code First 更新数据库, 数据库迁移
  5. BNUOJ 1006 Primary Arithmetic
  6. html颜色字体字符代码
  7. Tengine:基于Nginx的衍生版
  8. Cannot find class for bean with name service
  9. Activation successful 数据库邮件无法发送
  10. 将war文件解压到指定目录