C++ 中的virtual关键词

动态绑定

所谓动态绑定,我的理解就是一个函数在调用之前无法得知参数的具体类型(基类还是派生类)。C++ Primer上描述了两种动态绑定的情况:

要触发动态绑定,必须满足两个条件:一、指定为虚函数的成员函数。二、通过基类类型的引用或指针进行函数调用。

基类和派生类的关系

派生类是由基类派生而来,其包含基类的所有内容,并进行扩展和修改(覆盖)。比如对基类Base和派生类Derived来说,我们可以说Derived就是Base类型的,也就是说在使用Base类型做形参的函数调用中都可以使用Derived类型。这个是安全的,因为派生类本身就包含了基类子对象。

virtual关键词

上面提到动态绑定的两个条件,第一条要求成员函数为虚函数。虚函数使用virtual关键词进行声明。现在看一个例子:

void printClass(const Base &item)
{
cout << item.size()<< item.price()<<endl;
}

其中,size()函数在基类Base中声明为普通成员函数,而price()函数在基类Base中声明为虚成员函数。类Derived是Base类的派生类,且在Derived类中对price()类进行了覆盖。对于以下调用:

Base base;
Derived derived;
printClass(base);
printClass(derived);

由于printClass的参数是基类类型,而size()函数是普通成员函数,因此两个函数调用时都调用了基类(派生类中包含基类的子对象)的size(),即Base::size()。而对于虚函数price()来说,第一个调用调用的是Base::price(),第二个调用的是Derived::price()。

C++ 中的virtual关键词的更多相关文章

  1. 【09】绝不在构造和析构过程中调用virtual方法

    1.绝不在构造和析构过程中调用virtual方法,为啥? 原因很简单,对于前者,这种情况下,子类专有成分还没有构造,对于后者,子类专有成分已经销毁,因此调用的并不是子类重写的方法,这不是程序员所期望的 ...

  2. C#中的Virtual

    在 C# 中,派生类可以包含与基类方法同名的方法. 基类方法必须定义为 virtual. 如果派生类中的方法前面没有 new 或 override 关键字,则编译器将发出警告,该方法将有如存在 new ...

  3. NO.8:绝不在构造或者析构过程中调用virtual函数

    在构造和析构执行期间不要调用virtual函数,因为这类调用从不会下降至derived class(比起当前执行构造函数和析构函数) 如果在base class 构造函数或者析构函数调用virtual ...

  4. VMware与Cisco DRAC中的virtual disk的对应关系

    笔者面临的问题如下: 笔者有一台Cisco C240的服务器, 其中有十块容量一样大的SAS的local disk, 一块SSD. 其中的两块SAS盘组成了一个RAID 1的virtual drive ...

  5. Effective C++ .09 不在构造和析构过程中调用virtual函数

    看过C++对象模型的话就可以知道,在构造基类时,完整的vtable没有建立起来(表项没有被相应的子类函数替换),因而无法调用到子类的函数(即构造函数中的virtual函数是本类里的方法,不是virtu ...

  6. java并发中的Synchronized关键词

    文章目录 为什么要同步 Synchronized关键词 Synchronized Instance Methods Synchronized Static Methods Synchronized B ...

  7. C#中的Virtual、Override和new关键词理解

    来源:http://blog.csdn.net/jackiezhw/article/details/2673992 在 C# 中,派生类可以包含与基类方法同名的方法. 基类方法必须定义为 virtua ...

  8. 该不该在C#中使用var关键词

    作为一个并不勤快的程序猿,在项目开发过程中总是想尽办法少写代码,对var关键词的使用自然不会放过,几乎在每个能使用var的地方都用了var,对此,很多朋友同事给出了不同的建议,觉得能不使用var关键词 ...

  9. 绝不在构造和析构函数中调用 virtual 函数

    看下面的这段代码,问 print调用的是基类还是派生类的版本? 答案是 基类... 可能大家会很惊讶,print不是virtual function 吗?为什么不是调用派生类的版本呢? 首先,当定义一 ...

随机推荐

  1. UVaLive 6809 Spokes Wheel (模拟)

    题意:给定两个16进制数,问你把它转成二进制后,把第一个向左或者向右旋转最少的次数同,使得第一个变成第二个. 析:也是比较水的,按照要求做就好,注意0的情况,可能会忘记. #pragma commen ...

  2. UVa 1312 Cricket Field (枚举+离散化)

    题意:在w*h的图上有n个点,要求找出一个正方形面积最大,且没有点落在该正方形内部. 析:枚举所有的y坐标,去查找最大矩形,不断更新. 代码如下: #include <cstdio> #i ...

  3. Arrays, Hashtables and Dictionaries

    Original article Built-in arrays Javascript Arrays(Javascript only) ArrayLists Hashtables Generic Li ...

  4. AForge学习笔记(列表)

    AForge学习笔记(11):AForge.Imaging.Textures Clouds texture:具有云彩的纹理效果,示例如下:             CloudsTexture text ...

  5. JavaScript寻踪OOP之路

    上一集中,重点介绍了谁动了你的代码.这里先总结一下:咱们的代码从敲下来到运行出结果,经历了两个阶段:分析期与运行期.在分析期,JavaScript分析器悄悄动了我们的代码:在运行期,JavaScrip ...

  6. MVC ajax 上传文件

    废话不多说,上代码: 用到的js文件: jquery.min.js jquery.easyui.min.js <input id="fileurl" onclick=&quo ...

  7. 解决 Cocos2d-x 中 Android.mk 手动添加源文件

    转自:http://blog.csdn.net/ypfsoul/article/details/8909178 Makefile Android.mk 引发的思索 在我们编写 Android 平台 c ...

  8. __declspec,__cdecl,__stdcall区别和作用

    _cdecl和__stdcall都是函数调用规范(还有一个__fastcall),规定了参数出入栈的 顺序和方法,如果只用VC编程的话可以不用关心,但是要在C++和Pascal等其他语言通信的时候就要 ...

  9. uva193 - Graph Coloring

    Graph Coloring You are to write a program that tries to find an optimal coloring for a given graph. ...

  10. 理解sizeof

    1.sizeof返回的是字节个数,内存编址的最小单元是字节.因此,空对象,bool值占用的内存也是一个字节. 2.可以对哪些东西求sizeof ? a.对象和类型.如int a; sizeof(a), ...