C++ 虚函数在基类与派生类对象间的表现及其分析

近来看了侯捷的《深入浅出MFC》,读到C++重要性质中的虚函数与多态那部分内容时,顿时有了疑惑。因为书中说了这么一句:使用“基类之指针”指向“派生类之对象”,由该指针只能调用基类所定义的函数,如果要让基类的指针使用派生类中定义的函数,就将该函数定义为虚函数

但在“Object slicing与虚函数”这一小节给出了一个及其经典的例子,它指出,在向上(即向基类)强制转型时,会造成对象内容的被切割

下面用示例进行说明:

 

#include "stdafx.h"
#include <iostream>
using namespace std;class A
{
public:virtual void fn(){cout<<"A fn"<<endl;}
};class B: public A
{
public:virtual void fn(){cout<<"B fn"<<endl;}
};int main(int argc, char* argv[])
{B b1;A a1=(A)b1;A * a2=(A*)&b1;a1.fn();a2->fn();return 0;
}


结果如下:

 


通过调试分析其内存模型如下:


可知,通过A  a1=(A)b1传值时,对象中指向虚函数表的指针__vfptr值不同,但是通过A *a2=(A*)&b1传址操作时,对象中指向虚函数表的指针__vfptr值是相同的,调用的是类B对象的虚函数表中虚函数fn()。注意,对象调用的是哪个类的虚函数就要看类对象的虚函数表中的函数是哪一个。这句话也好理解,a1虚函数表中fn()是A::fn(),a2虚函数表中fn()是B::fn(),所以出现以上结果。

在如下包含父类的父类的继承中:

class A
{
public:
virtual void fn(){cout<<"A fn"<<endl;}
};

class B: public A
{
public:
virtual void fn(){cout<<"B fn"<<endl;}
};

class C: public B
{
public:

};

C c;
A a1=(C)c;
A * a2=(C*)&c;
a1.fn();
a2->fn();

这时,a1虚函数表中fn()为A::fn(),a2虚函数表中fn()为B::fn(),因为类C对象的虚函数表中fn()为B::fn(),a2中指向虚函数表的指针值与类C对象指向虚函数表的指针值相同。

侯捷的书中有句话是这么对它进行解释的:由于(A)b1.fn()是传值而非传地址操作,编译器以所谓的拷贝构造函数把A对象内容复制了一份,使得b1的虚函数表内容与A对象的虚函数表内容相同

看来,得多读圣贤书啊,读懂读透啊!

 

转载于:https://www.cnblogs.com/pangblog/p/3327622.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/421515.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php评论盖楼怎么实现,dedecms评论盖楼实现楼层数,类似腾讯、网易的评论(5.5/5.6版)...

DEDE评论效果&#xff1a;修改后的效果&#xff1a;修改步骤一、织梦dedecms5.5版本(5.6版本请往下看)1、修改/plus/feedback_ajax.php文件的第131行(如果你没改过)下面是修改之前的代码&#xff1a;$qmsg {quote}{title}.$row[username]. 的原帖&#xff1a;{/title}{content…

datagridview绑定与详细说明 (搜集)

1、实现一个用于处理数据库教程数据检索的详细信息的方法。 下面的代码示例实现一个 getdata 方法&#xff0c;该方法对一个 sqldataadapter 组件进行初始化&#xff0c;并使用该组件填充 datatable。 然后&#xff0c;将 datatable 绑定到 bindingsource 组件。请确保将 conne…

matlab显示二值直方图,图像灰度变换、二值化、直方图

1、灰度变换1)灰度图的线性变换Gnew Fa * Gold Fb。Fa为斜线的斜率&#xff0c;Fb为y轴上的截距。Fa>1 输出图像的对比度变大&#xff0c;否则变小。Fa1 Fb≠0时&#xff0c;图像的灰度上移或下移&#xff0c;效果为图像变亮或变暗。Fa-1&#xff0c;Fb255时&#xff0c;发…

blender怎么移动骨骼,Blender学习笔记-(015)创建骨骼绑定及权重绘制操作详解

骨骼创建绑定具体操作如下&#xff1a;1&#xff1a; 【ShiftA】创建基础骨骼。(也可以通过打开Blender的插件Rigging&#xff1a;Rigify&#xff0c;生成自定义骨骼)2&#xff1a;点击骨骼&#xff0c;按【Tab】键进入编辑模式&#xff0c;选中创建骨骼端&#xff0c;按【E】拖…

[MySQL binlog实战] 增量同步与数据搜索~从入门到精通

学习基础知识&#xff0c;并落实到实际场景&#xff08;增量同步数据搜索&#xff09; 对基础知识不感兴趣的&#xff0c;可以直接跳到应用场景 文章目录 binlog是什么简介产生方式文件格式statementrowmixed 怎么办开启 binlog查看 binlog其他查看相关命令运维查看 binlog设置…

从硬核科幻小说《三体》中看嵌入式

1 2 3 4 5 6 7 8 9 转载于:https://www.cnblogs.com/OleNet/p/3352189.html

php快速排序和二分查找法,二分查找及快速排序

小朋友二分查找和快速排序思想上有很大的相似度&#xff0c;就是做一个起始点&#xff0c;开始往左右做动作&#xff0c;也同样是由递归实现&#xff0c;当然也可以不用递归实现。但是我觉得也不能用php内置特有的函数- -&#xff0c;我找了很多php的快速排序&#xff0c;几乎都…

extractCSS – 帮助你从 HTML 中快速分离出 CSS

extractCSS 是一个免费的基于 Web 的应用程序&#xff0c;能够从 HTML 中提取风格相关的信息&#xff0c;包括 id、class 和内联样式&#xff0c;而且输出可以定制&#xff08;缩进和括号的用法&#xff09;。该工具非常有用&#xff0c;当我们快速创建一个使用了内联样式的 HT…

php项目安装器,php项目安装器程序源码,php通用安装程序

php项目安装器程序源码,php通用安装程序一个安装器的源码&#xff0c;最简单的看一下emlog 也可以&#xff01;文件目录结构index.php 程序首页│ ├─conf 安装后配置文件目录├─data    目录写入测试目录└─install 安装程序目录 │ index.php   安装程…

Python开发环境Wing IDE 5.0测试第八版发布

Wing IDE是著名的Python开发工具&#xff0c;是Wingware公司的主要产品。从1999年起&#xff0c;Wingware公司便开始专注于Python开发设计。Wing IDE在十几年的发展中&#xff0c;不管完善。其强大设计理念包括&#xff1a;编辑工具丰富&#xff0c;编译测试版权一体化&#xf…

WPF自定义控件 —— 装饰器

摘自&#xff1a;http://www.cnblogs.com/Curry/archive/2009/09/16/1567757.html 顾名思义就是装饰用的&#xff0c;也就是说不改变原有的控件结构&#xff0c;但可以为控件添加一些新的功能&#xff0c;或是为控件的显示外观增加些东西。如MSDN中的例子&#xff1a; 本来Text…

Netty Associated -- ByteBuf

ByteBuf ByteBuf是Netty的Server与Client之间通信的数据传输载体.他提供了一个byte数组(byte[])的抽象视图 buffer创建 我们推荐通过一个Unpooled的帮助方法来创建新的buffer而不是通过调用独立的构造器来创建 随机访问索引 就像普通的原声字节数组一样, ByteBuf使用零基坐标(z…

php 根号2计算过程,根号2以及π的计算--关于无理数的畅想

[导读]这两篇文章里&#xff0c;我发现不需要那些老师教的范式也能很好地理解那些现代概念&#xff0c;并且理解的更深刻。这两篇文章里&#xff0c;我发现不需要那些老师教的范式也能很好地理解那些现代概念&#xff0c;并且理解的更深刻。我一般假设自己从来没有学过微积分&a…

任务分配与时间估计

各成员的任务分配与时间估计如下&#xff1a; 项目所需总时间为&#xff1a; 转载于:https://www.cnblogs.com/buaa-smile/p/3383374.html