C++ virtual虚函数
#include<iostream>
using namespace std;
class Base{
public:
void m()
{
cout << "it's Base's m() " << endl;
}
virtual void f()
{
cout << "it's Base's f()" << endl;
}
};
class Sub: public Base
{
void m()
{
cout << "it's Sub's m()" << endl;
}
void f()
{
cout << "it's Sub's f()" << endl;
}
};
void main()
{
Base* base = new Sub;
base->f();
base->m();
}
上述是以Base为基类,并且Sub派生了Base,同时复写了两个函数f(),m()
当在主函数main里用Base类型的指针指向Sub类型对象,此时利用Base指针调用f()和m(),那么这个时候问题就来了。
在默认情况下Base类的指针会调用当前类型的方法,也就是Base::f(),Base::m(),那么应该输出的都是Base方法中的语句
然而结果输出的是
为什么会产生这种原因呢?
因为父类的f()是虚函数,那么当基类指针调用它的派生类对象时,会默认调用多态性对象的相应方法,于是就解释了为什么Base* base->f()调用了派生类Sub的f()的方法,
由此我们可以知道虚函数Virtual主要是为了解决多态性问题,因为一个基类方法定义后,它的派生类对象会针对此方法进行不同的覆盖实现,即多态性,若你此时利用基类的指针来指向基类的多态性子类,那么就需要利用virtual修饰基类方法,从而可以来调用你所需要的派生类的方法而避免了调用基类的此方法。
Virtual是C++ OO机制中很重要的一个关键字。在类Base中加了Virtual关键字的函数就是虚拟函数(例如函数print),于是在Base的派生类Derived中就可以通过重写虚拟函数来实现对基类虚拟函数的覆盖。当基类Base的指针point指向派生类Derived的对象时,对point的print函数的调用实际上是调用了Derived的print函数而不是Base的print函数。这是面向对象中的多态性的体现。
还有虚函数析构函数,应用在这样一个问题:在基类为抽象类,并且基类指针指向派生类,想要删除这个基类指针指向的内存时
先看第一种情况
de<iostream>
using namespace std;
class Base{
public:
Base()
{
}
~Base()
{
cout << "Base has deleted" << endl;
}
};
class Sub: public Base
{
public:
Sub()
{
}
~Sub()
{
cout << "Sub has delete" << endl;
}
};
void main()
{
Base* base = new Sub;
delete base;
base = NULL;
}
看运行结果

此时是用基类Base指针去操作继承类Sub,在delete Base*指针后,我们可以从结果得到只调用了基类的析构函数,但是派生类的析构函数并没有调用,这相当于内存只是删除了一一半,还有一半内存为删除,导致了内存泄漏,此时则需要用到虚析构函数,来达到调用派生类的析构函数来删除内存空间的目的,也就是下面这种情况:
#include<iostream>
using namespace std;
class Base{
public:
Base()
{
}
virtual ~Base()
{
cout << "Base has deleted" << endl;
}
};
class Sub: public Base
{
public:
Sub()
{
}
~Sub()
{
cout << "Sub has delete" << endl;
}
};
void main()
{
Base* base = new Sub;
delete base;
base = NULL;
}
运行结果如下图所示

此时我们可以看到在基类析构函数加了Virtual变成虚函数后,成功地调用了基类和派生类的析构函数,从而实现了基类指针指向内存的完全释放。
虚析构函数工作的方式是:最底层的派生类的析构函数最先被调用,然后各个基类的析构函数被调用。
但是有一点要注意,当某个类没有虚函数时,那么此类不会被当作基类,此时定义虚析构函数只会增加内存开销,因为需要开启一个虚函数列表来储存。
以上只是个人的小总结,若有错误,欢迎前来纠正!
C++ virtual虚函数的更多相关文章
- 【2016-10-13】【坚持学习】【Day4】【virtual 虚函数】
定义一个基类,有一个虚函数 定义三个子类,分别继承,重写,New,这个虚函数 abstract class Test { public virtual void Prinf() { Console ...
- C++\virtual 虚函数、纯虚函数
前提摘要: 虚函数联系到多态,多态联系到继承.所以本文中都是在继承层次上做文章.没了继承,什么都没得谈. 虚函数定义: 指向基类的指针或引用在操作它的多态类(子类/派生类)对象时,会根据不同的类对象, ...
- 23.C++- 继承的多种方式、显示调用父类构造函数、父子之间的同名函数、virtual虚函数
上章链接: 22.C++- 继承与组合,protected访问级别 继承方式 继承方式位于定义子类的”:”后面,比如: class Line : public Object //继承方式是publi ...
- C#语法-虚方法详解 Virtual 虚函数
虚方法 / Virtual 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- 心分享. ...
- c++中virtual 虚函数
转载: https://www.cnblogs.com/weiyouqing/p/7544988.html 在面向对象的C++语言中,虚函数(virtual function)是一个非常重要的概念. ...
- 104.virtual虚函数多态与异构数据结构
#include "mainwindow.h" #include <QApplication> #include <list> #include <Q ...
- C++之虚函数和多态
干货较多-需要自己深思理解: C++支持两种多态性: 1.编译时多态性(静态绑定-早绑定) 在程序编译阶段即可以确定下来的多态性 通过使用 重载机制(重载函数)实现 (模板)http://blog.c ...
- TControl的显示函数(5个非虚函数,4个虚函数)和三个例子的执行过程(包括SetParent的例子)
// 9个显示函数 procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); virtual; // 虚函数,important 根据父控 ...
- c++ 深入理解虚函数
为什么使用虚函数?什么是虚函数?虚函数是为了解决什么问题? 面向对象的三大特征: 封装 多态 继承 普通虚函数 虚析构函数 纯虚函数 抽象类 接口类 隐藏 vs 覆盖 隐藏与覆盖之间的关系 早绑定和晚 ...
随机推荐
- .Net Task<T>的一种比较神奇的卡死情况(Wait/Result卡死, await能得到结果)
出现的环境.Net4.0 + WebApi1(4.0.30506.0) + Microsoft.Bcl.Async.1.0.168 自己死活看不出原因, 分享出来给大家看看,希望有人能找到问题的关键 ...
- 未能加载文件或程序集“System.Web.Http.WebHost, Version=4.0.0.0, ”或它的某一个依赖项。系统找不到指定的文件。
一:错误提示 "未能加载文件或程序集"System.Web.Http.WebHost, Version=4.0.0.0, Culture=neutral, PublicKeyTok ...
- 改进网站设计的免费jQuery插件Top 7
Animate Scroll.js是一个简单的jQuery插件,它用来为滚动增加延迟效果.同时你还可以自定义滚动样式(30多种滚动效果)和滚动速度,还有一个可以操纵”滚动结束位置”的”padding” ...
- Win8 app判断网络连接状态
Win8 app判断网络连接状态 NetworkInformation.NetworkStatusChanged += NetworkInformation_NetworkStatusChanged; ...
- 不可或缺 Windows Native (16) - C++: 函数重载, 缺省参数, 内联函数, 函数模板
[源码下载] 不可或缺 Windows Native (16) - C++: 函数重载, 缺省参数, 内联函数, 函数模板 作者:webabcd 介绍不可或缺 Windows Native 之 C++ ...
- SSH实例(5)
在src中新建struts.xml文件: <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE ...
- 改变 TMemo 的背景颜色 (Firemonkey)
说明:展示使用程序码改变 Firemonkey TMemo 的背景颜色. 适用:XE6 源码下载:[原創]Memo改背景色_XE6.zip //---------------------------- ...
- 安卓actionbar源码
安卓actionbar源码,该源码转载源码天堂android源码频道的,Actionbar是一个标识应用程序和用户位置的窗口功能.源码我也上传到源码天堂了,大家也可以去那边下载就行了. 本地:源码源码 ...
- PHP高效率写法
1.尽量静态化: 如果一个方法能被静态,那就声明它为静态的,速度可提高1/4,甚至我测试的时候,这个提高了近三倍.当然了,这个测试方法需要在十万级以上次执行,效果才明显.其实静态方法和非静态方法的效率 ...
- 【精心推荐】12款很好用的 jQuery 图片滚动插件
这里收集了12款很好用的 jQuery 图片滚动插件分享给大家.jQuery 作为最流行的 JavaScript 框架,使用简单灵活,同时还有许多优秀的插件可供使用.其中最令人印象深刻的应用之一就是各 ...