动态绑定与静态绑定的小结(改)

2023-11-01

接下来的一段话是我从一位博客大佬那里copy来的:

对象的静态类型:对象在声明时采用的类型。是在编译期确定的。
对象的动态类型:目前所指对象的类型。是在运行期决定的。对象的动态类型可以更改,但是静态类型无法更改。
静态绑定:绑定的是对象的静态类型,某特性(比如函数)依赖于对象的静态类型,发生在编译期。
动态绑定:绑定的是对象的动态类型,某特性(比如函数)依赖于对象的动态类型,发生在运行期。

在此贴上大佬的文章:
(http://blog.csdn.net/chgaowei/article/details/6427731)
下面用c++primer第五版p550的代码说明一下:

#include <iostream>
using namespace std;
class Base{
public:
    virtual int fcn();
};
class D1:public Base{
public:
    //隐藏了基类的fcn,这个fcn不是虚函数
    //D1继承了Base::fcn()的定义
    int fcn(int);       //形参列表与Base中的fcn不一致
    virtual void f2();  //是一个新的虚函数,在Base中不存在
};
class D2:public D1{
public:
    int fcn();          //是一个非虚函数,隐藏了D1::fcn(int)
    int fcn(int);       //覆盖了Base的虚函数fcn
    void f2();          //覆盖了D1的虚函数f2
};
int main(){
    Base bobj;D1 dlobj;D2 d2obj;
    Base *bp1=&bobj,*bp2=&d1obj,*bp3=&d2obj;
    bp1->fcn();         //虚调用,将在运行时调用Base::fcn
    bp2->fcn();         //虚调用,将在运行时调用Base::fcn,因为D1中并没有fcn,编译器在Base中找到符合条件的fcn,于是调用Base的fcn
    bp3->fcn();         //虚调用,将在运行时调用D2::fcn,D2中存在fcn()
    return 0;
}

除了这些动态绑定,还有静态绑定,静态绑定是对于非虚函数的调用。调用的函数与对象的静态类型有关,最后一句也是摘自大佬的一句话:只有虚函数才使用的是动态绑定,其他的全部是静态绑定。目前我还没有发现不适用这句话的,如果有错误,希望你可以指出来。

//——————————————————
此处是我第二次增加的内容,内容是关于动态绑定中虚表和虚指针的状态和过程的图解和代码

#include<iostream>
using namespace std;
class base {
public:
    virtual void print() {
        cout << "base::print()" << endl;
    }
    virtual void goo() {
        cout << "base::goo()" << endl;
    }
};
class devired :public base {
public:
    virtual void print() {
        cout << "devired::print()" << endl;
    }
    virtual void go() {
        cout << "devired::go()" << endl;
    }
};
int main(void) {
    devired b;
    typedef void(*Fun)(void);
    Fun pfun = NULL;
    for (int i = 0; i < 3; i++)
    {
        pfun = (Fun)*((int*)*(int*)(&b)+i);
        pfun();
    }
    system("pause");
}

结果是:
devired::print()
base::goo()
devired::go()
可见devired::print()覆盖了base的print()这样也就实现了为什么能够多态了,用到的就是向上规则。还需要强调的是虚表是这几个类共享的。
下面摘自侯捷老师译注的《深度探索c++对象模型》:
注:代码是简易的,并没有完全实现的,另外图表不好画,就直接贴上了侯捷老师书上的截图

#include<iostream>
using namespace std;
class point {
public:
    virtual ~point() { cout << "~point()" << endl; }
    virtual point& mult(float) = 0;
    float x()const { return _x; }
    virtual float y()const { return 0; }
    virtual float z()const { return 0; }
protected:
    point(float x = 0.0) {};
    float _x;
};
class point2 :public point {
protected:
    float _y;
public:
    point2(float x = 0.0, float y = 0.0):point(x),_y(y){}
    ~point2() { cout << "~point2()" << endl; }
    point2& mult(float);
    float y()const { return _y; }
};
class point3 :public point2 {
protected:
    float _z;
public:
    point3(float x=0.0,float y=0.0,float z=0.0):point2(x,y),_z(z){}
    ~point3() { cout << "~point3()" << endl; }
    point3&mult(float);
    float z()const { return _z; }
};
void main(void) {

}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

动态绑定与静态绑定的小结(改) 的相关文章

  • 有没有办法分析 WCF 应用程序的性能?

    我们正在尝试测量我们的系统的性能 该系统是一个使用 WCF 调用的 NET 3 5 应用程序 问题是到目前为止 我们无法分析这些调用中的方法 编写了一个 winforms 客户端应用程序来测试我们的系统 我们尝试使用ANTS 4 Profi
  • 如何拦截 .Net 中第三方库对非虚拟方法的调用?

    我认为我需要的是 net 人们称之为 透明动态代理 的东西 但到目前为止我所看到的所有实现 Castle DynamicProxy Spring NET AOP 等 都要求我至少执行以下操作之一 将拦截的方法声明为虚拟方法 包装类并创建包装
  • 自定义可视化 Web 部件属性 sharepoint

    我在 Visual Studio 2012 中创建可视 Web 部件属性时遇到问题 我被提及http msdn microsoft com en us library ee231551 aspx http msdn microsoft co
  • 将数据集导出到 EXCEL

    我使用以下代码将数据库表中的字段导出到 Excel 中 我想要做的是能够编写一条 SQL 语句从多个表中检索字段并将其导出到 Excel 中 这段代码只允许我导出一张表 另外 如何显示保存提示对话框 示例代码将不胜感激 非常感谢 prote
  • 实体框架 - 循环更新属性

    我正在尝试找到一种方法来循环 EF 对象的属性并更新这些属性的值 更具体地说 我有 50 个字段 其中最多填充 50 个下拉列表 所有 50 个可能都需要填充 也可能不需要填充 为了解决这个问题 我有一个中继器 最多可以创建 50 个 DD
  • 每个 CPU 核心处于 C0 电源状态的时间

    任何帮助弄清楚如何做到这一点都会很棒 在过去一秒内 每个 CPU 核心处于 C0 电源状态的时间有多少 这是针对 Mac 应用程序的 因此需要 Objective C cocoa 和 c OS X 没有任何公开 CPU c 状态的 API
  • 无法使用 Unity 函数在 Visual Studio Code 中获得完整的 Intellisense

    好吧 我知道这个问题已经被问过并回答过很多次了 但我花了大约 3 天的时间试图解决这个问题 但到目前为止我所做的一切都没有奏效 我基本上在 Visual Studio Code 中有部分智能感知 也就是说 它似乎只识别 Unity 类和变量
  • 无法更新 .mdf 数据库,因为该数据库是只读的(Windows 应用程序)

    我使用 C 创建了一个数据库 Windows 应用程序 我的应用程序在 Windows XP 上成功运行 但在 Vista 或 Windows 7 系统上无法正确执行 我的应用程序显示类似以下内容的消息 无法更新 mdf 数据库 因为该数据
  • WIX 自动生成 GUID *?

    假设我生成产品 ID 为 的 WIX XML 文件 另外 对于每个组件 GUID 我都使用
  • 尝试将元素推入向量

    在头文件 我没有编写 中 已经定义了一个结构体 如下所示 struct MemoryMessage public boost counted base public FastAlloc explicit MemoryMessage Memo
  • NHibernate 中具有不同类型答案的问题

    我正在尝试找到一个问卷问题的简洁解决方案 假设我有一个Questionnaire类有一个集合Answers e g public class Questionnaire public virtual ISet
  • 在 C# 中加密并在 Flex 中解密

    我需要解密 Flex 中的一些数据 这些数据是用 C 加密并写入文件的 为了简单起见 我选择使用 as3crypto As3 库和 Bruce Schneier C 库 AS3 as3加密链接 http code google com p
  • 如何带参数调用外部程序?

    我想在我的代码中调用一个 Windows 程序 并使用代码本身确定的参数 我不想调用外部函数或方法 而是调用 WinXP 环境中的实际 exe 或批处理 脚本文件 C 或 C 将是首选语言 但如果使用任何其他语言更容易完成此操作 请告诉我
  • 无论表单上的焦点控件如何,如何捕获 Keys.F1?

    我使用了 KeyDown 事件和一些简单的代码 例如if e KeyCode Keys F1 捕获在表单上按下 F1 但如果表单上有一些文本框 或者表单上有一些带有 Dock Fill 的电子表格 则上面的代码将毫无用处并且不执行任何操作
  • 选择要重写哪个基类的方法

    鉴于以下情况 class Observer public virtual void Observe Parameter p 0 template
  • 为什么 OOP 中静态类的最佳实践有所不同?

    我目前正在阅读有关 Java 最佳实践的内容 我发现根据这本书 https rads stackoverflow com amzn click com 0321356683我们必须优先选择静态类而不是非静态类 我记得在 C 最佳实践中 我们
  • 修改公共属性的访问修饰符是否是重大更改?

    如果我将公共属性的 setter 的访问修饰符从私有更改为公共 是否会导致引用它的其他程序集发生任何重大更改 UPDATE 这个问题是我 2012 年 1 月博客的主题 https ericlippert com 2012 01 09 ev
  • 使用 LINQ to SQL 的 .NET 架构的最佳设计实践(DAL 必要吗?我们真的可以使用 POCO吗?要采用的设计模式吗?)

    我避免在 net arch n 层架构上编写看起来像是另一个线程的内容 但请耐心等待 希望我和其他人一样 在选择用于企业应用程序的架构时 考虑到当今的趋势和新兴技术 仍然没有 100 满意或不清楚应采取的最佳方法 我想我正在寻求大众社区对方
  • 为什么C#不支持多重继承? [复制]

    这个问题在这里已经有答案了 可能的重复 C 应该包含多重继承吗 https stackoverflow com questions 191691 should c include multiple inheritance 为什么C 不支持多
  • 如何在Asp.Net Core中自定义开发者异常页面?

    这常见于ConfigureStartup cs 文件的方法具有如下所示的代码 if env IsDevelopment app UseDeveloperExceptionPage new DeveloperExceptionPageOpti

随机推荐

  • 【独家源码】ssm高校试卷管理系统i0lzr应对计算机毕业设计困难的解决方案

    本项目包含程序 源码 数据库 LW 调试部署环境 文末可获取一份本项目的java源码和数据库参考 系统的选题背景和意义 选题背景 高校试卷管理是教学工作中的重要环节 涉及到试卷的编写 存储 分发和评阅等多个方面 然而 传统的试卷管理方式存在
  • [转]Java 线程池的原理与实现

    最近在学习线程池 内存控制等关于提高程序运行性能方面的编程技术 在网上看到有一哥们写得不错 故和大家一起分享 分享 Java 线程池的原理与实现这几天主要是狂看源程序 在弥补了一些以前知识空白的同时 也学会了不少新的知识 比如 NIO 或者
  • SoftwareSerial库的使用——Arduino软件模拟串口通信

    除HardwareSerial外 Arduino还提供了SoftwareSerial类库 它可以将你的其他数字引脚通过程序模拟成串口通信引脚 通常我们将Arduino UNO上自带的串口称为硬件串口 而使用SoftwareSerial类库模
  • 如何开启计算机cpu虚拟化,电脑开启虚拟化设置的方法 如何开启虚拟化设置

    虚拟化设置的开启其实很简单 因为大家没有接触和操作过 所以一开始会不知所措 虚拟化设置的开启其实很简单 因为大家没有接触和操作过 所以一开始会不知所措 小编在这里为广大玩家深度总计虚拟化开启方法 方便大家在电脑端更流畅的体验手机游戏 虚拟化
  • maven工程依赖的jar包,在本地仓库有,但是pom.xml文件却报错找不到jar包

    例如 Missing artifact com ibm db2 db2jcc license cisuz jar 10 1 但在我本地的仓库中却存在这个jar包 查找了很多的资料发现了两种解决方法 第一种 在eclipse中的window
  • 透彻了解inlining的里里外外——条款30

    Inline函数 多棒的点子 它们看起来像函数 动作像函数 比宏好得多 见条款2 可以调用它们又不需要蒙受函数调用所招致的额外开销 你还能要求更多吗 你实际获得的比想到的还多 因为 免除函数调用成本 只是故事的一部分而已 编译器最优化机制通
  • 2021美赛F题

    2021年 问题E 重新优化食物系统 最近的事件向我们表明 我们的全球粮食系统即使在世界的某些地区也是不稳定的 它通常服务于全世界 这些不稳定的部分原因是我们目前的全球气候变化 庞大的国内和国际食品生产商和经销商体系 这个食物系统 使食物的
  • CUDA矩阵乘法优化

    前言 纸上的来终觉浅 绝知此事要躬行 naive写法 一个矩阵的乘法简单如下 C A B 一般用gemm A B C M N K 来表示 其中的m n k代表的位置如下 默认是k表示消失的纬度 上图的红色虚线围起来的是一个block要负责的
  • MySQL存储引擎InnoDB与Myisam的六大区别

    MySQL有多种存储引擎 每种存储引擎有各自的优缺点 可以择优选择使用 MyISAM InnoDB MERGE MEMORY HEAP BDB BerkeleyDB EXAMPLE FEDERATED ARCHIVE CSV BLACKHO
  • MySQL注入绕安全狗脚本 -- MySQLByPassForSafeDog,以及端口爆破工具 -- PortBrute配置使用

    工具介绍 此Tamper仅仅适用于MySQL数据库 在SQLMap使用过程中添加参数 tamper MySQLByPassForSafeDog 安装与使用 1 安装网站安全狗Apache最新版 2 启用安全狗 不加MySQLByPassFo
  • vue.js组件详解

    一 组件的概念及复用 1 1 为什么要使用组件 组件 component 是vue js最核心的功能 用来实现局部 特定 功能效果的代码集合 html css js image 组件是可复用的 Vue 实例 把一些公共的模块抽取出来 然后写
  • anaconda创建和删除环境

    一 创建环境 在菜单栏中打开Anaconda Prompt 它是一个命令行界面 我们输入下面命令创建环境 这里的py37是我随意起的环境名 大家任意取好记为主 后面的python版本也是自由指定 中间只有一个等号 例如我这里是想创建pyth
  • unicode编码表

    unicode编码表 转载于 近來情轉深的博客 http jlqzs blog 163 com blog static 2125298320070101826277 另附一个汉字转化unicode编码的网页工具 http www bangn
  • 使用别人编译的动态库gdb,路径不匹配

    如果你在调试时需要在动态库中打断点 但动态库的路径是别人的路径 可以使用 GDB 的 set substitute path 命令将动态库路径替换为你本地的路径 具体来说 执行以下步骤 启动 GDB 并加载调试目标 使用 info shar
  • WebFlux ServerHttpRequest RequestBody 读取

    MockServerHttpRequest request MockServerHttpRequest post test body test DecoderHttpMessageReader
  • 安卓开发--不走弯路,5步教你快速实现拍照功能(基于安卓13)

    先展示效果 实现基本逻辑很简单 大致5步为 点击按钮 启动相机 拍照 保存相片 展示相片 但是这里面有一些细节对于初次接触安卓的用户并不友好 比如笔者我 折腾了一阵子才梳理出基本流程 下面我将分步骤说明 按着我的步骤即可快速实现拍照功能 目
  • Update function的问题和解决方案

    DN的过账一般使用的是都是 Function WS DELIVERY UPDATE 其实这是一个经常使用到的函数 注意 这不是一个BAPI 只是一个函数 但是这个函数里面有一个update funtion 所以这个函数并没有返回参数 ret
  • 【RK3399】I3399烧写Debian系统详解

    00 目录 文章目录 00 目录 01 驱动安装 02 镜像文件烧写 03 问题讨论 04 附录 01 驱动安装 1 1 没有安装驱动的时候 显示感叹号 1 2 解压DriverAssitant v5 1 1 zip 1 3 双击Drive
  • Tomcat的下载安装及使用

    目录 一 tomcat简介 二 tomcat的下载 1 进入官网界面 2 选择你使用的版本 3 选择下载 4 将下载好的tomcat安装包进行解压 5 Tomcat的目录结构 6 启动tomcat 7 关闭tomcat 8 解决乱码问题 8
  • 动态绑定与静态绑定的小结(改)

    接下来的一段话是我从一位博客大佬那里copy来的 对象的静态类型 对象在声明时采用的类型 是在编译期确定的 对象的动态类型 目前所指对象的类型 是在运行期决定的 对象的动态类型可以更改 但是静态类型无法更改 静态绑定 绑定的是对象的静态类型