Microsoft Word - A200809-686.doc



Similar documents

说 明 为 了 反 映 教 运 行 的 基 本 状 态, 为 校 和 院 制 定 相 关 政 策 和 进 行 教 建 设 与 改 革 提 供 据 依 据, 校 从 程 资 源 ( 开 类 别 开 量 规 模 ) 教 师 结 构 程 考 核 等 维 度, 对 2015 年 春 季 期 教 运 行 基

何 秋 琳 张 立 春 视 觉 学 习 研 究 进 展 视 觉 注 意 视 觉 感 知

第2章 数据类型、常量与变量


《C语言基础入门》课程教学大纲

马 克 思 主 义 公 正 观 的 基 本 向 度 及 方 法 论 原 则!! # #

I

<4D F736F F D C3E6CFF2B6D4CFF3A3A8B5DAC8FDD5C220C0E0CCD8D0D4A3A92E646F63>

抗 战 时 期 国 民 政 府 的 银 行 监 理 体 制 探 析 % # % % % ) % % # # + #, ) +, % % % % % % % %

Microsoft Word - 第7章 图表反转形态.doc

西 南 民 族 学 院 学 报 哲 学 社 会 科 学 版 第 卷 资 料 来 源 中 国 统 计 年 鉴 年 年 新 中 国 五 十 年 统 计 资 料 汇 编 中 国 人 口 统 计 年 鉴 年 数 据 资 料 来 源 中 国 统 计 年 鉴 中 国 统 计 出 版 社 年 版 资 料 来 源

<433A5C446F63756D656E E E67735C41646D696E F725CD7C0C3E65CC2DBCEC4CFB5CDB3CAB9D3C3D6B8C4CFA3A8BCF2BBAFA3A95CCAB9D3C3D6B8C4CF31302D31392E646F63>

评 委 : 徐 岩 宇 - 个 人 技 术 标 资 信 标 初 步 审 查 明 细 表 序 号 投 标 单 位 投 标 函 未 按 招 标 文 件 规 定 填 写 漏 填 或 内 容 填 写 错 误 的 ; 不 同 投 标 人 的 投 标 文 件 由 同 一 台 电 脑 或 同 一 家 投 标 单

评 委 : 李 炎 斌 - 个 人 技 术 标 资 信 标 初 步 审 查 明 细 表 序 号 投 标 单 位 投 标 函 未 按 招 标 文 件 规 定 填 写 漏 填 或 内 容 填 写 错 误 的 ; 不 同 投 标 人 的 投 标 文 件 由 同 一 台 电 脑 或 同 一 家 投 标 单

修改版-操作手册.doc

HSK( 一 级 ) 考 查 考 生 的 日 常 汉 语 应 用 能 力, 它 对 应 于 国 际 汉 语 能 力 标 准 一 级 欧 洲 语 言 共 同 参 考 框 架 (CEF) A1 级 通 过 HSK( 一 级 ) 的 考 生 可 以 理 解 并 使 用 一 些 非 常 简 单 的 汉 语

登录、注册功能的测试用例设计.doc

伊 犁 师 范 学 院 611 语 言 学 概 论 全 套 考 研 资 料 <2016 年 最 新 考 研 资 料 > 2-2 语 言 学 纲 要 笔 记, 由 考 取 本 校 本 专 业 高 分 研 究 生 总 结 而 来, 重 点 突 出, 借 助 此 笔 记 可 以 大 大 提 高 复 习 效

国债回购交易业务指引

 编号:


( ) 信 号 与 系 统 Ⅰ 学 科 基 础 必 修 课 教 周 2016 年 06 月 13 日 (08:00-09:35) ( )

,,,,, :,, (.,, );, (, : ), (.., ;. &., ;.. &.., ;, ;, ),,,,,,, ( ) ( ),,,,.,,,,,, : ;, ;,.,,,,, (., : - ),,,, ( ),,,, (, : ),, :,

课程类 别

¹ º ¹ º 农 业 流 动 人 口 是 指 户 口 性 质 为 农 业 户 口 在 流 入 地 城 市 工 作 生 活 居 住 一 个 月 及 以 上 的 流 动 人 口 非 农 流 动 人 口 是 指 户 口 性 质 为 非 农 户 口 在 流 入 地 城 市 工 作 生 活 居 住 一 个

随着执业中医师资格考试制度的不断完善,本着为我校中医学专业认证服务的目的,本文通过对我校中医类毕业生参加2012年和2013年的中医执业医师考试成绩及通过率、掌握率进行分析,并与全国的平均水平进行差异比较分析,以此了解我校执业中医师考试的现状,进而反映我校中医类课程总体教学水平,发现考核知识模块教学中存在的不足,反馈给相关学院和教学管理部门,以此提高教学和管理水平。

中 国 软 科 学 年 第 期!!!

一 从 分 封 制 到 郡 县 制 一 从 打 虎 亭 汉 墓 说 起

目 录 一 系 统 访 问... 1 二 门 户 首 页 申 报 用 户 审 核 用 户... 2 三 系 统 登 录 用 户 名 密 码 登 录 新 用 户 注 册 用 户 登 录 已 注 册 用

定 位 和 描 述 : 程 序 设 计 / 办 公 软 件 高 级 应 用 级 考 核 内 容 包 括 计 算 机 语 言 与 基 础 程 序 设 计 能 力, 要 求 参 试 者 掌 握 一 门 计 算 机 语 言, 可 选 类 别 有 高 级 语 言 程 序 设 计 类 数 据 库 编 程 类

一 公 共 卫 生 硕 士 专 业 学 位 论 文 的 概 述 学 位 论 文 是 对 研 究 生 进 行 科 学 研 究 或 承 担 专 门 技 术 工 作 的 全 面 训 练, 是 培 养 研 究 生 创 新 能 力, 综 合 运 用 所 学 知 识 发 现 问 题, 分 析 问 题 和 解 决

untitled

思 想 政 治 理 论 经 核 查 无 误 思 想 政 治 理 论 经 核 查 无 误 思 想 政 治 理 论 经 核 查 无 误 思 想

2006年顺德区高中阶段学校招生录取分数线

目 录 关 于 图 标... 3 登 陆 主 界 面... 3 工 单 管 理... 5 工 单 列 表... 5 搜 索 工 单... 5 工 单 详 情... 6 创 建 工 单... 9 设 备 管 理 巡 检 计 划 查 询 详 情 销 售 管

3 复 试 如 何 准 备 4 复 试 成 绩 计 算 5 复 试 比 例 6 复 试 类 型 7 怎 么 样 面 对 各 种 复 试 04 05

0 年 上 半 年 评 价 与 考 核 细 则 序 号 部 门 要 素 值 考 核 内 容 考 核 方 式 考 核 标 准 考 核 ( 扣 原 因 ) 考 评 得 3 安 全 生 产 目 30 无 同 等 责 任 以 上 道 路 交 通 亡 人 事 故 无 轻 伤 责 任 事 故 无 重 大 质 量

!!


龚 亚 夫 在 重 新 思 考 基 础 教 育 英 语 教 学 的 理 念 一 文 中 援 引 的 观 点 认 为 当 跳 出 本 族 语 主 义 的 思 维 定 式 后 需 要 重 新 思 考 许 多 相 连 带 的 问 题 比 如 许 多 发 音 的 细 微 区 别 并 不 影 响 理 解 和

( 二 ) 现 行 统 一 高 考 制 度 不 利 于 培 养 人 的 创 新 精 神,,,,,,,,,,,,, [ ],,,,,,,,,,, :, ;,,,,,,? ( 三 ) 现 行 统 一 高 考 制 度 不 利 于 全 体 学 生 都 获 得 全 面 发 展,, [ ],,,,,,,,,,,

类 似 地, 又 可 定 义 变 下 限 的 定 积 分 : ( ). 与 ψ 统 称 为 变 限 积 分. f ( ) d f ( t) dt,, 注 在 变 限 积 分 (1) 与 () 中, 不 可 再 把 积 分 变 量 写 成 的 形 式 ( 例 如 ) 以 免 与 积 分 上 下 限 的

抗 日 战 争 研 究 年 第 期

第 期 李 伟 等 用 方 法 对 中 国 历 史 气 温 数 据 插 值 可 行 性 讨 论

Microsoft Word - 第3章.doc

深圳市新亚电子制程股份有限公司

模 型 假 设 假 设 假 设 假 设 假 设 假 设 模 型 建 立 与 推 导

二 工 资 制 度 与 教 师 道 德 风 险 行 为

第二讲 数列

内 容 二 : 建 立 并 完 善 了 三 点 的 网 络 教 学 管 理 体 系 内 容 三 : 注 重 培 养 学 生 的 听 说 能 力 14


名 称 生 命 科 学 学 院 环 境 科 学 1 生 物 学 仅 接 收 院 内 调 剂, 初 试 分 数 满 足 我 院 生 物 学 复 试 最 低 分 数 线 生 命 科 学 学 院 生 态 学 5 生 态 学 或 生 物 学 生 命 科 学 学 院


(Microsoft Word - NCRE\314\345\317\265\265\367\325\37313\324\27221\272\3051.doc)

一 开 放 性 的 政 策 与 法 规 二 两 岸 共 同 的 文 化 传 承 三 两 岸 高 校 各 自 具 有 专 业 优 势 远 见 杂 志 年 月 日


全国建筑市场注册执业人员不良行为记录认定标准(试行).doc

Microsoft Word - 文件汇编.doc

Microsoft PowerPoint - plan03.ppt

i 1) 系 统 运 作 前 设 定 *1. [2.1 网 页 主 机 名 称 设 定 ] -- 设 定 校 务 系 统 的 主 机 IP 地 址, 以 供 其 他 个 人 电 脑 连 接 及 使 用 该 系 统 *2. [2.3.1 输 入 / 修 改 学 校 资 料 ] -- 输 入 系 统 使

抗 日 战 争 研 究 % 年 第 期! # # % %

!!!!!!!!!!

<4D F736F F D C4EAB9A4B3CCCBB6CABFCAFDD1A7D7A8D2B5BFCEBFBCCAD4B4F3B8D9D3EBD2AAC7F3>


徐天宏:《基因天堂》.doc

导 数 和 微 分 的 概 念 导 数 的 几 何 意 义 和 物 理 意 义 函 数 的 可 导 性 与 连 续 性 之 间 的 关 系 平 面 曲 线 的 切 线 和 法 线 导 数 和 微 分 的 四 则 运 算 基 本 初 等 函 数 的 导 数 复 合 函 数 反 函 数 隐 函 数 以

ETF、分级基金规模、份额变化统计

黄 金 原 油 总 持 仓 增 长, 同 比 增 幅 分 别 为 4.2% 和 4.1% 而 铜 白 银 以 及 玉 米 则 出 现 减 持, 减 持 同 比 减 少 分 别 为 9.4%,9.4% 以 及 6.5% 大 豆, 豆 粕 结 束 连 续 4 周 总 持 仓 量 增 长, 出 现 小 幅

中 日 信 息 化 的 比 较 与 合 作 一 中 日 信 息 化 的 规 模 比 较

<4D F736F F D20B2CEBFBC3232C6DAD1A7CFB0D3EBCBBCBFBCC4DAD2B3>

2014年中央财经大学研究生招生录取工作简报

& & ( & ) +,! #

<4D F736F F D20B9D8D3DAB0BABBAAA3A8C9CFBAA3A3A9D7D4B6AFBBAFB9A4B3CCB9C9B7DDD3D0CFDEB9ABCBBE C4EAC4EAB6C8B9C9B6ABB4F3BBE1B7A8C2C9D2E2BCFBCAE92E646F6378>

Microsoft PowerPoint - plan03.ppt

<433A5C C6B73625C B746F705CB9FABCCAD6D0D2BDD2A9D7A8D2B5B8DFBCB6BCBCCAF5D6B0B3C6C6C0C9F3C9EAC7EBD6B8C4CFA3A CDA8D3C3B0E6A3A92E646F63>

国 际 中 国 研 究 动 态 是 中 国 社 会 科 学 院 国 际 中 国 学 研 究 中 心 出 品 的 以 介 绍 国 际 中 国 问 题 研 究 最 新 成 果 为 宗 旨 的 电 子 杂 志 计 划 每 月 出 版 一 期 除 编 译 和 摘 编 网 络 和 中 外 期 刊 库 上 可

关于修订《沪市股票上网发行资金申购

第 六 章 债 券 股 票 价 值 评 估 1 考 点 一 : 债 券 价 值 的 影 响 因 素 2

新, 各 地 各 部 门 ( 单 位 ) 各 文 化 事 业 单 位 要 高 度 重 视, 切 实 加 强 领 导, 精 心 组 织 实 施 要 根 据 事 业 单 位 岗 位 设 置 管 理 的 规 定 和 要 求, 在 深 入 调 查 研 究 广 泛 听 取 意 见 的 基 础 上, 研 究 提

, (CIP) /. - : ISBN R657.1 CIP (2003) mm1230m m 1/ IS BN

教师上报成绩流程图

!!!!!

生产支援功能 使用说明书(IP-110 篇)

Template BR_Rec_2005.dot

Microsoft Word - JAVA3.rtf

上证指数

珠江钢琴股东大会

<4D F736F F D20B3D6B2D6CFDEB6EEB1EDB8F1D7EED6D52E646F63>

金 不 少 于 800 万 元, 净 资 产 不 少 于 960 万 元 ; (3) 近 五 年 独 立 承 担 过 单 项 合 同 额 不 少 于 1000 万 元 的 智 能 化 工 程 ( 设 计 或 施 工 或 设 计 施 工 一 体 ) 不 少 于 2 项 ; (4) 近 三 年 每 年

第1篇 道路桥梁工程技术核心专业课程标准及学习绩效考评体系

年 第 期 % %! & % % % % % % &

际 联 考 的 非 美 术 类 本 科, 提 前 批 本 科 体 育 类 第 一 批 第 二 批 第 三 批 的 理 工 类 和 文 史 类 本 科 平 行 志 愿, 考 生 可 以 填 报 6 所 院 校 志 愿 符 合 贫 困 地 区 专 项 计 划 和 农 村 考 生 专 项 计 划 报 考

精 勤 求 学 自 强 不 息 Born to win! 解 析 : 由 极 限 的 保 号 性 知 存 在 U ( a) 当 a 时 f ( ) f ( a) 故 f ( ) 在 点 a 不 取 极 值 f ( ) f ( a) f ( ) f ( a) lim lim a a a a ( a)

002 电 子 科 学 与 工 程 学 院 拟 招 生 150 人 联 系 人 : 周 老 师, 电 话 物 理 电 子 学 电 路 分 析 电 磁 场 理 论 01 电 磁 物 理 与 微 波 电 子 学 02 光 子 学 与 光 电 技 术 03 微 纳


浙 江 海 洋 学 院 417 普 通 生 态 学 与 鱼 类 学 全 套 考 研 资 料 <2016 年 最 新 考 研 资 料 > 2-2 基 础 生 态 学 笔 记, 此 笔 记 为 高 分 研 究 生 复 习 所 用, 借 助 此 笔 记 可 以 大 大 提 高 复 习 效 率, 把 握 报

采 取 行 动 的 机 会 90% 开 拓 成 功 的 道 路 2

2 熟 悉 Visual Basic 的 集 成 开 发 环 境 3 了 解 可 视 化 面 向 对 象 编 程 事 件 驱 动 交 互 式 开 发 等 基 本 概 念 4 了 解 Visual Basic 的 特 点 环 境 要 求 与 安 装 方 法 1 Visual Basic 开 发 应 用

第二部分 阅读理解(Part II Reabing Comprehension)

Transcription:

从 内 存 布 局 深 入 剖 析 继 承 与 多 态 匡 翠 芸 武 汉 科 技 大 学 计 算 机 学 院, 湖 北 武 汉 (430065) E-mail: kuciyun@126.com 摘 要 : 在 面 向 对 象 程 序 设 计 中, 使 派 生 类 继 承 基 类 的 虚 函 数, 再 定 义 一 个 指 向 派 生 类 对 象 的 基 类 指 针 可 以 轻 松 实 现 动 态 绑 定 程, 那 么 编 译 器 是 如 何 做 到 动 态 绑 定 以 及 基 类 的 析 构 函 数 为 什 么 要 申 明 为 虚 析 构 函 数 呢. 本 文 避 开 普 通 的 调 试 方 法, 通 过 精 巧 设 计 实 例, 安 插 指 针 来 对 面 向 对 象 的 类 的 继 承 与 多 态 的 研 究, 从 内 存 的 角 度 深 入 剖 析 了 具 有 虚 函 数 的 基 类 和 派 生 类 对 象 的 内 存 布 局 和 结 构 组 成, 分 析 动 态 绑 定 的 实 现 原 理, 从 而 在 编 写 程 序 的 时 候 出 现 不 必 要 的 错 误, 使 设 计 出 来 的 类 更 合 理, 避 免 类 拥 肿. 关 键 词 : 多 态 性 ; 继 承 性 ; 虚 函 数 ; 虚 函 数 表 ; 虚 拟 指 针 ; 动 态 联 编 ; 内 存 布 局 1. 引 言 在 C++ 面 向 对 象 程 序 设 计 中, 继 承 与 多 态 是 OOP 最 重 要 的 两 个 特 性 继 承 的 目 的 是 复 用, 继 承 复 用 包 括 两 方 面 的 复 用 : 抽 象 ( 接 口 ) 复 用 和 实 现 ( 过 程 ) 复 用 多 态 的 目 的 是 要 将 抽 象 复 用 及 实 现 复 用 剥 离 开 来 那 么 派 生 类 是 如 何 实 现 继 承 基 类 的 属 性 和 方 法, 虚 函 数 是 如 何 实 现 多 态? 庖 丁 解 牛 的 功 力 不 在 其 刀 的 锋 利, 而 在 对 牛 筋 骨 脉 络 的 理 解 一 般 的 研 究 方 法 是 通 过 [1] 调 试 从 汇 编 代 码 去 分 析, 但 有 其 不 足 : 一 是 不 懂 汇 编 的 人 无 法 深 入 了 解, 二 是 不 能 从 整 体 上 把 握 对 象 继 承 与 多 态 的 内 存 布 局 本 文 正 是 从 内 存 布 局 作 为 切 入 点, 精 心 设 计 C++ 代 码 来 从 整 体 上 深 入 剖 析 这 两 大 特 性, 使 OOP 人 员 对 继 承 与 多 态 的 筋 骨 脉 络 了 如 指 掌, 在 实 际 程 序 设 计 中 做 到 心 中 有 数, 有 的 放 矢 2. 设 计 C++ 代 码 分 析 内 存 布 局 2.1 虚 拟 指 针 的 存 在 Class A1{int a;}; Class A2{int a; Virtual void f1(){} Virtual f2(){} }; sizeof(a1) = 4; sizeof(a2) = 8;A1 的 字 节 数 为 4 在 我 们 的 意 料 之 中, 而 在 A2 中 我 们 增 加 了 两 个 虚 函 数, 这 时 的 字 节 数 却 为 8. 原 来 编 译 器 对 每 个 包 含 虚 函 数 的 类 创 建 一 个 虚 表 [2] ( 称 为 VTable), 此 VTable 由 类 的 所 有 对 象 所 共 用, 同 时 编 译 器 也 会 为 这 个 类 的 每 个 类 对 象 秘 密 地 嵌 入 一 个 变 量, 即 一 个 指 向 自 己 虚 表 的 指 针 称 为 虚 拟 指 针 (VPTR) 正 是 因 为 有 了 VPTR 的 存 在, 所 以 后 者 的 所 占 字 节 为 8. 2.2 设 计 实 例 由 上 面 的 分 析 可 知, 对 于 有 虚 函 数 的 类 在 实 例 化 (Instance) 时 都 有 一 个 VPTR, 那 么, 对 象, 虚 表 的 结 构 是 由 什 么 组 成, 结 构 如 何? 编 译 器 是 怎 么 实 现 动 态 联 编? 为 此 我 们 设 计 两 个 类 CBase 与 CDeri, 其 中 后 者 派 生 于 前 者, 为 了 看 清 楚 动 态 的 真 面 目, 我 特 意 在 CBase 中 定 义 两 个 虚 函 数, 其 中 只 有 一 个 在 在 派 生 类 中 重 写. 而 在 派 生 类 中 再 加 一 个 虚 函 数 用 来 分 析 VTable 的 情 况. 具 体 如 下 : class CBase{ public: CBase(){nBaseData = 10;} ~CBase(){} Void Function0(){cout<<"<2> Address="<<&nBaseData<<" CBase::nBaseData= "<<nbasedata<<endl;} - 1 -

virtual void VFunction1(){cout<<" CBase::VFunction1< >"<<endl;} virtual void VFunction2(){cout<<" CBase::VFunction2< >"<<endl;} private: int nbasedata; }; class CDeri : public CBase{ public: CDeri(){nDeriData = 20;} ~CDeri(){} void Function0(){cout<<"<3> Address= "<<&nderidata<<" CDeri::nDeriData= "<<nderidata<<endl;} virtual void VFunction2(){cout<<" CDeri::VFunction2< >"<<endl;} virtual void VFunction3(){cout<<" CDeri::VFunction3< >"<<endl;} private: int nderidata; }; 类 设 计 好 了. 要 清 楚 VTable 的 结 构, 可 以 通 过 获 取 VPTR, 因 为 VPTR 指 VTable, 依 上 面 的 分 析 知 道, 在 每 个 有 虚 函 数 的 对 象 中 编 译 器 都 会 放 个 一 个 VPTR,. 为 此 定 义 函 数 指 针 : typedef void (*pfun)(); pfun fun; 并 设 计 获 取 函 数 指 针 的 函 数 CallMemberFunction() 如 下 : void CallMemberFunction(unsigned long *pmemberfunction, const int &noffset) { fun = (pfun)((*(unsigned long *)(pmemberfunction + noffset))); cout<<"<"<<(noffset+1)<<"> "<<(pmemberfunction + noffset)<< --> <<fun; (*fun)(); } 同 时 为 了 明 晰 对 象 的 结 构, 为 此 设 计 函 数 SetMemberData() 用 来 设 置 成 员 变 量 的 值, 如 下 : void SetMemberData(unsigned long *pdatavalue, const int &noffset, const int &ndatavalue) { int *pdata = (int *)(pdatavalue + noffset); *pdata = ndatavalue; } 最 后 设 计 主 函 数, 在 其 中 先 实 例 化 基 类 对 象, 然 后 实 例 派 生 类 对 象, 目 的 在 于 对 比 基 类 与 派 生 类 在 内 存 中 的 布 局. 如 下 : int main(int argv, char * argc[ ]) { CBase *pbase = new CBase; unsigned long *VPTR1 = (unsigned long *)(pbase); cout<<"<1> Address= "<<VPTR1<<" Pointer of Virtl Fun"<<endl; unsigned long *pvmemfun1 = (unsigned long *)(*VPTR1); pbase->function0(); for (int j = 0; j < 2; j ++) CallMemberFunction(pVMemFun1, j); CBase *pderi = new CDeri; unsigned long *VPTR = (unsigned long *)(pderi); cout<<"<1> Address= "<<VPTR<<" Pointer of Virtl Fun"<<endl; unsigned long *pvmemfun = (unsigned long *)(*VPTR); SetMemberData(VPTR, 1, 40); SetMemberData(VPTR, 2, 80); pderi->function0(); ((CDeri *)pderi)->function0(); for (int i = 0; i < 3; i ++) CallMemberFunction(pVMemFun, i); delete pbase; delete pderi; return 0;} - 2 -

2.3. 深 入 分 析 (1) 在 主 函 数 中 先 定 义 基 类 的 对 象 指 针 pbase, 再 进 行 强 制 类 型 转 化 为 (unsigned long *) 目 的 是 取 VPTR, 因 为 VPTR 指 向 VTable, 所 以 (*VPTR) 就 是 VTable 的 首 地 址 [3], 然 后 取 地 址 加 偏 移 量 强 制 转 化 为 函 数 指 针 类 型, 从 下 面 图 1 输 出 内 存 结 果 可 知, 在 对 象 中 首 地 址 中 存 放 的 是 VPTR( 地 址 :00A91BD8), 后 紧 跟 基 类 的 成 员 变 量 ( 地 址 :00A91BDC). 而 在 VTable 中, 按 声 明 的 先 后 次 序 存 放 的 是 基 类 的 虚 函 数 地 址, 由 此 可 画 出 对 应 在 内 存 的 分 布 如 : 图 2. 图 1: 基 类 的 内 存 结 果 图 2: 基 类 的 对 应 内 存 结 构 (2) 然 后 在 主 函 数 中 定 义 派 生 类 的 对 象 指 针 pderi, 同 样 对 其 进 行 强 制 类 型 转 换 从 而 得 到 VPTR, 再 调 用 SetMemberData() 去 修 改 基 类 与 派 生 类 的 私 有 成 员 变 量, 调 用 CallMemberFunction() 去 调 用 所 有 的 虚 函 数, 这 个 函 数 先 输 出 VTable 中 每 一 项 表 的 地 址 及 所 存 放 的 函 数 地 址. 从 下 图 3 输 出 内 存 结 果 可 知, 在 对 象 中 首 地 址 同 样 是 VPTR( 地 址 : 00A90930), 其 后 是 基 类 的 成 员 变 量 ( 地 址 : 00A90934), 然 后 才 是 派 生 类 成 员 变 量 ( 地 址 : 00A90938). 对 于 VTable 而 言, 在 VTable 的 第 一 个 地 址 中 所 指 向 的 函 数 地 址 没 有 变 ( 地 址 : 004011E5), 那 是 因 为 在 派 生 类 中 没 有 重 写 VFunction1, 而 在 派 生 类 中 重 写 了 VFunction2 且 在 第 二 个 地 址 所 指 向 的 VFunction 的 地 址 改 变 了 ( 地 址 : 0040119A 变 为 地 址 : 004010A0), 第 三 个 是 派 生 类 新 加 的 虚 函 数 地 址. 由 此 知 在 VTable 中, 放 置 了 这 个 类 中 或 是 它 的 基 类 中 所 有 虚 函 数 的 地 址, 这 些 虚 函 数 的 顺 序 都 是 一 样 的, 每 个 虚 函 数 都 在 VTable 中 占 了 了 个 表 项, 保 存 着 一 条 跳 转 到 它 的 入 口 地 址 的 指 令, 所 以 通 过 偏 移 量 可 以 容 易 地 找 到 所 需 的 函 数 体 的 地 址 如 果 派 生 类 没 有 重 写 虚 函 数, 那 么 VTable 中 保 留 基 类 虚 函 数 的 地 址, 如 果 重 写 了 相 应 的 虚 函 数, 那 么 VTable 中 的 地 址 就 会 改 变 成 指 向 派 生 类 的 虚 函 数 地 址 如 果 派 生 类 有 自 己 的 虚 函 数, 那 么 VTable 中 就 会 添 加 该 项 正 是 由 于 第 二 个 地 址 里 面 的 内 容 改 变, 从 而 实 现 动 态 联 编 技 术. 调 用 虚 函 数 的 时 候, 它 先 根 据 Vtable 找 到 入 口 地 址 再 执 行, 从 而 实 现 了 动 态 联 编. 于 是 可 画 出 对 应 内 存 分 布 如 : 图 4. 图 3: 派 生 类 的 内 存 结 果 图 4: 派 生 类 对 应 内 存 结 构 - 3 -

3. 结 论 (1) 如 果 该 类 没 有 虚 拟 函 数, 则 不 存 在 虚 拟 函 数 表. 当 一 个 类 含 有 虚 函 数 时, 编 译 器 就 会 为 这 个 类 生 成 一 个 VTable, 编 译 器 另 外 还 为 每 个 类 的 对 象 提 供 了 一 个 虚 拟 指 针 (VPTR), 这 个 指 针 指 向 了 对 象 所 属 类 的 虚 表, 并 且 这 个 VPTR 在 对 象 的 头 部. (2) 对 象 ( 含 虚 函 数 的 类 ) 是 由 VPTR 和 成 员 变 量 组 成, 无 论 有 多 少 个 虚 函 数, 只 有 一 个 VPTR, 与 成 员 函 数 ( 如 :Function0) 无 关, 因 此 对 象 的 大 小 由 一 个 指 针 的 字 节 大 小 加 上 成 员 变 量 所 占 字 节 的 大 小 之 和, 有 时 候 为 了 存 取 的 效 率, 还 要 加 上 字 节 对 齐 (Align). (3) 虚 函 数 表 (VTable) 的 结 构 实 质 是 数 组,( 如 在 基 类 中 的 地 址 为 : 0047016C, 00470170) 在 派 生 类 中 地 址 为 004701DC, 004701E0, 004701E4) 而 这 个 数 组 中 所 存 储 的 是 指 向 函 数 地 址 的 指 针, 即 VTable 的 结 构 是 函 数 指 针 数 组 的 结 构 [4]. 因 此 只 要 取 到 VPTR, 然 后 采 用 偏 移 量 很 容 易 实 现 函 数 的 调 用. (4) 在 派 生 类 中, 如 果 没 有 重 写 (Override) 基 类 的 虚 函 数, 那 么 在 VTable 中 保 留 基 类 虚 函 数 的 地 址 ( 如 :VFunction1), 如 果 派 生 类 重 写 了, 则 在 VTable 中 把 基 类 对 应 虚 函 数 地 址 用 派 生 类 虚 函 数 地 址 覆 盖 ( 如 :VFunction2). 如 果 在 派 生 类 中 加 入 新 的 虚 函 数, 则 在 VTable 中 后 面 加 入 对 应 虚 函 数 的 地 址 ( 如 :VFunciton3). 即 :VTable 按 照 类 中 虚 函 数 声 明 的 顺 序 一 一 填 入 函 数 地 址, 派 生 类 会 继 承 基 类 的 VTable( 当 然 还 会 有 其 它 可 继 承 的 成 员 ), 当 在 派 生 类 中 修 改 虚 函 数 时, 同 时 派 生 类 中 虚 表 中 的 内 容 也 随 之 被 修 改, 表 中 相 应 的 元 素 已 经 不 是 基 类 的 函 数 地 址, 而 是 派 生 类 的 函 数 地 址, 虚 表 可 以 继 承, 如 果 派 生 类 没 有 重 写 虚 函 数, 那 么 基 类 虚 表 中 仍 然 会 有 该 函 数 的 地 址, 只 不 过 这 个 地 址 指 向 的 是 基 类 的 虚 函 数 实 现. (5) 在 对 象 或 者 在 VTable 的 结 构 中, 基 类 的 组 成 在 前, 派 生 类 在 后 ( 如 : 在 pderi 对 象 中 :nbasedata 在 前,nDeriData 在 后, 在 VTable 中,VFunction1,VFunction2 在 前, 而 VFunction3 在 后 ) 而 在 每 个 类 中 都 是 按 声 明 的 先 后 次 序 分 配 内 存. (6) 从 上 面 的 对 象 结 构 分 析 可 知, 普 通 成 员 函 数 在 对 象 中 不 占 内 存, 调 用 时 简 单 地 跳 转 到 一 个 固 定 地 址 ( 编 译 时 分 配 好 ); 同 样 静 态 成 员 函 数 ( 这 里 没 有 举 例 ) 也 不 占, 因 为 静 态 成 员 函 数 只 属 于 类, 为 所 有 对 象 共 用. 不 属 于 某 个 特 定 的 对 象. (7) 本 例 中 利 用 SetMemberData() 函 数 实 现 了 类 体 外 对 私 有 变 量 值 的 修 改, 这 也 提 供 了 一 个 修 改 私 有 变 量 的 方 法, 访 问 效 率 较 高, 尤 其 对 一 些 经 过 多 重 或 多 层 继 承 得 到 的 类 对 象 的 数 据 成 访 问, 使 用 该 方 法 需 要 对 类 成 员 的 布 局 十 分 清 楚 ( 尤 其 是 有 字 节 对 齐 时 ), 否 则 很 容 易 产 生 非 法 操 作, 甚 至 导 致 系 统 崩 溃, 这 种 方 法 也 说 明 了 类 封 装 性 是 不 完 全 可 靠, 从 此 也 可 以 得 出, 基 类 的 成 员 变 量, 派 生 类 是 可 以 继 承 的, 只 是 在 派 生 类 中 的 成 员 函 数 跟 对 象 都 不 能 访 问 而 已 ( 编 译 器 不 能 通 过 ) 4. 高 效 应 用 毫 无 疑 问, 有 了 继 承 性, 使 得 代 码 重 复 利 用 率 很 高, 明 显 可 以 缩 短 开 发 周 期 但 由 上 的 分 析 知 道, 派 生 类 的 对 象 中 会 继 承 基 类 中 的 所 有 成 员 变 量, 包 括 私 有 成 员 变 量, 这 样 会 带 来 空 间 开 销 同 样 有 了 虚 函 数 使 类 的 设 计 更 灵 活 也 更 强 大, 同 样 时 间 和 空 间 的 开 销 不 可 避 免 也 大 了 ( 不 是 直 接 跳 转 到 编 译 时 分 配 的 固 定 地 址, 而 是 要 先 得 到 VPTR, 然 后 经 过 偏 移 量 取 得 虚 函 数 地 址, 然 后 再 调 用 ). 所 以 在 设 计 类 的 时 候 除 非 十 分 明 确 以 后 这 个 类 会 被 继 承 且 里 面 的 函 数 会 被 改 写, 才 加 关 键 字 Virtual 因 为 如 果 继 承 的 层 次 比 较 深, 那 么 所 有 直 接 和 间 接 基 类 的 数 据 成 员, 虚 函 数 都 会 在 派 生 类 的 对 象 中, 虽 然 在 对 象 中 无 论 多 少 个 VF, 只 增 加 一 个 VPTR, - 4 -

但 VTable 会 变 得 很 庞 大 所 以 在 实 际 OOP 中, 我 们 就 可 以 做 到 心 中 有 数, 有 的 放 矢 5. 结 束 语 (1) 以 上 结 论 的 运 行 环 境 : 系 统 为 Windows XP 编 译 器 为 Visual Studio C++ 6.0. 对 于 其 他 的 编 译 器, 具 体 实 现 并 不 完 全 相 同, 但 都 大 同 小 异.( 如 Linux 平 台 上 的 GNU C++ 编 译 器 就 把 指 向 VTable 的 虚 拟 指 针 (VPTR) 放 在 对 象 尾 部 而 不 是 头 部, 而 且 VTable 中 仅 仅 存 放 虚 函 数 的 入 口 地 址, 而 不 是 跳 转 到 虚 函 数 的 指 令. (2) 以 上 征 对 仅 仅 是 简 单 的 单 继 承 的 情 况, 对 于 横 向 ( 如 : 多 继 承 ), 纵 向 ( 如 虚 继 承, 更 深 层 次 继 承 ) 等 更 复 杂 的 情 况, 由 于 篇 幅 所 限 在 此 不 加 以 深 入, 但 剖 析 思 想 大 同 小 异. 参 考 文 献 [1] 蓝 雯 飞.C++ 语 言 的 多 态 性 应 用 研 究 [J] 计 算 机 时 代 1998(19)6 [2] 候 捷 译. 深 入 探 索 C++ 对 象 模 型 [M] 武 汉 : 华 中 科 技 大 学 出 版 社 [3] 张 宇. 淺 谈 多 态 中 的 虚 拟 指 针 (VPTR)[J] 武 汉 市 教 育 科 学 研 究 院 学 报 2006.11.4 [4] 彭 建 盛. 多 态 性 在 C++ 面 向 对 象 程 序 设 计 中 的 实 现 [J] 河 池 学 院 学 报 2004(20)4 Inside Analysis the Inheritance and Polymorophism from the Memory Layout KUANG Cui-Yun College of Computer Science and Technology WuHan University of Science and Technology WuHan (430065) Abstract In OOP, the derived class inherited the basic class that have a virtual function, and then define a basic pointer that point to the object of derive class can easily achieve dynamic binding.the compiler is how to achieve dynamic binding and why the destructed function of the base class must defined used by virtual keyword. The paper avoid this debugging method, research the inheritance and polymorophism of Object-Orient programming through the exquisitely designing example and insert the pointer, Thorough analysis the memoy layout and composition of object and Virtual Function Table, the analysis the principle of dynamic binding, avoid makeing the unnecessary mistakes and a lots of inderited class,can designing reasonable class while programming. Keywords: Polymorphism; Inheritance Virtual Function; Virtual Function Table; Virtual Pointer; Dynamic Binding; Memory Layout - 5 -