首页 > 编程语言 >C++PrimerPlus:第十三章类和继承:静态联编和动态联编001

C++PrimerPlus:第十三章类和继承:静态联编和动态联编001

时间:2024-06-16 12:31:34浏览次数:24  
标签:PrimerPlus BrassPlus 联编 C++ ViewAcct 引用 Brass 指针

第十三章类和继承:静态联编和动态联编

提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
例如:静态联编和动态联编


提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录


前言

提示:大概内容:

程序调用函数时,将使用哪个可执行代码块呢?编译器负责回答这个问题。将源代码中的函数调用解释为执行特定的函数代码块被称为函数名联编(binding)。在C语言中,这非常简单,因为每个函数名都对应一个不同的函数。在C++中,由于函数重载的缘故,这项任务更复杂。编译器必须查看函数参数以及函数名才能确定使用哪个函数。然而,C/C++编译器可以在编译过程完成这种联编。在编译过程中进行联
编被称为静态联编(static binding),又称为早期联编(early binding)。然而,虚函数使这项工作变得更困难。正如在程序清单13.10所示的那样,使用哪一个函数是不能在编译时确定的,因为编译器不知道用户将选择哪种类型的对象。所以,编译器必须生成能够在程序运行时选择正确的虚方法的代码,这被称为动态联编(dynamic binding),又称为晚期联编(late binding)知道虚方法的行为后,下面深入地探讨这一过程,首先介绍C++如何处理指针和引用类型的兼容性


提示:以下是本篇文章正文内容,下面案例可供参考

一、指针和引用类型的兼容性

在C++中,动态联编与通过指针和引用调用方法相关,从某种程度上说,这是由继承控制的。公有继承建立 is-a关系的一种方法是如何处理指向对象的指针和引用。通常,C++不允许将一种类型的地址赋给另一种类型的指针,也不允许一种类型的引用指向另一种类型:

double x = 1;
int* pi = &x;//赋值无效,指针类型不匹配
long &rl = x;//无效的赋值,不匹配的引用类型

二、使用步骤

1.引入库

代码如下(示例):

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
import  ssl
ssl._create_default_https_context = ssl._create_unverified_context

下面的初始化是允许的:
然而,正如您看到的,指向基类的引用或指针可以引用派生类对象,而不必进行显式类型转换。例如,

BrassPlus dilly("zhang yong",44444,3333);
Brass* pb = &dilly;	//ok
Brass&rb = dilly ;//ok

将派生类引用或指针转换为基类引用或指针被称为向上强制转换(upcasting),这使公有继承不需要进行显式类型转换。该规则是is-a关系的一部分。BrassPlus对象都是Brass对象,因为它继承了Brass 对象所有的数据成员和成员函数。所以,可以对 Brass对象执行的任何操作,都适用于BrassPlus对象。因此,为处理 Brass 引用而设计的函数可以对 BrassPlus 对象执行同样的操作,而不必担心会导致任何问题。将指向对象的指针作为函数参数时,也是如此。向上强制转换是可传递的,也就是说,如果从BrassPlus 派生出BrassPlusPlus类,则Brass指针或引用可以引用Brass对象、BrassPlus对象或 BrassPlusPlus 对象。

相反的过程–将基类指针或引用转换为派生类指针或引用–称为向下强制转换(downcasting)。如果不使用显式类型转换,则向下强制转换是不允许的。原因是is-a关系通常是不可逆的。派生类可以新增数据成员,因此使用这些数据成员的类成员函数不能应用于基类。例如,假设从Employee 类派生出 Singe类,并添加了表示歌手音域的数据成员和用于报告音域的值的成员函数range(),则将rage()方法应用于Employee 对象是没有意义的。但如果允许隐式向下强制转换,则可能无意间将指向 Singer 的指针设置为一个Employee对象的地址,并使用该指针来调用range()方法(参见图13.4)。

函数都调用虚方法 ViewAcct():
对于使用基类引用或指针作为参数的函数调用,将进行向上转换。请看下面的代码段,这里假定每个

void fr(Brass& rb);//use rb.ViewAcct()
void fp(Brass* pb);//uses pb->ViewAcct()
void fv(Brass b);//uses b.ViewAcct()
int main()
{
	Brass b("zhang yong",12345,6789);
	BrassPlus bp("Betyt,z",2222,2222.0);
	fr(b);//uses Brass::ViewAcct()
	fr(bp);//uses BrassPlus::ViewAcct()
	fp(b);//uses Brass::ViewAcct()
	fp(bp);//uses BrassPlus::ViewAcct()
	fv(b);//uses Brass::ViewAcct()
	fv(bp);//uses Brass::ViewAcct()
	...
}

在这里插入图片描述

按值传递导致只将 BrassPlus对象的 Brass 部分传递给函数 fv()。但随引用和指针发生的隐式向上转换导致函数 f()和 ()分别为 Brass 对象和 BrassPlus对象使用 Brass::ViewAcct()和 BrassPlus::ViewAcct()。隐式向上强制转换使基类指针或引用可以指向基类对象或派生类对象,因此需要动态联编。C++使用虚成员函数来满足这种需求。

把上面的例子运行,测试结果
在这里插入图片描述


总结

提示:这里对文章进行总结:
对运行结果做总结
1,fr的引用,执行基类和派生类指向正常。
2,fp指针,直接报错没法运行
3,fv的传类,虽然不报错都能运行,但是函数指向是基类函数,这个需要注意

标签:PrimerPlus,BrassPlus,联编,C++,ViewAcct,引用,Brass,指针
From: https://blog.csdn.net/zhyjhacker/article/details/139716735

相关文章

  • C++前期概念(重)
    目录命名空间命名空间定义1.正常的命名空间定义2.命名空间可以嵌套 3.头文件中的合并 命名空间使用命名空间的使用有三种方式:1:加命名空间名称及作用域限定符(::)2:用using将命名空间中某个成员引入3:使用usingnamespace命名空间名称引入C++输入&输出说明:std......
  • 蓝桥杯备考冲刺必刷题(C++) | 3791 珠宝的最大交替和
    学习C++从娃娃抓起!记录下蓝桥杯备考比赛学习过程中的题目,记录每一个瞬间。附上汇总贴:蓝桥杯备考冲刺必刷题(C++)|汇总-CSDN博客【题目描述】小莉是一位珠宝设计师,她非常喜欢玩珠子。她有一个长度为N......
  • 蓝桥杯备考冲刺必刷题(C++) | 3250 最大的卡牌价值
    学习C++从娃娃抓起!记录下蓝桥杯备考比赛学习过程中的题目,记录每一个瞬间。附上汇总贴:蓝桥杯备考冲刺必刷题(C++)|汇总-CSDN博客【题目描述】给定nnn副卡牌,每张卡牌具......
  • 算法02 递归算法及其相关问题【C++实现】
    递归在编程中,我们把函数直接或者间接调用自身的过程叫做递归。递归处理问题的过程是:通常把一个大型的复杂问题,转变成一个与原问题类似的,规模更小的问题来进行求解。递归的三大要素函数的参数。在用递归解决问题时,要合理地去设计函数的参数,达到当前问题与子问题之间的变化,可......
  • C++全栈聊天项目(22) 气泡聊天对话框
    气泡聊天框设计我们期待实现如下绿色的气泡对话框对于我们自己发出的信息,我们可以实现这样一个网格布局管理NameLabel用来显示用户的名字,Bubble用来显示聊天信息,Spacer是个弹簧,保证将NameLabel,IconLabel,Bubble等挤压到右侧。如果是别人发出的消息,我们设置这样一个网......
  • 【C++学习笔记 3】指针
    指针的本质指针实际上就是一个整数,存储着一个内存地址。不必执着于用“类型”的概念区分,那只是为了方便设计出来的,所有的指针,本质上都是一个整数,存储着一个内存的地址。#include<iostream>#defineLOG(x)std::cout<<x<<std::endlintmain(){ intvar=8; ......
  • 2024华为OD机试真题-堆内存申请-(C++/Python)-C卷D卷-100分
    2024华为OD机试题库-(C卷+D卷)-(JAVA、Python、C++)题目描述有一个总空间为100字节的堆,现要从中新申请一块内存,内存分配原则为:优先紧接着前一块已使用内存,分配空间足够且最接近申请大小的空闲内存。输入描述第1行是1个整数,表示期望申请的内存字节数第2到第N行是用空格......
  • 2024华为OD机试真题-围棋的气-(C++/Python)-C卷D卷-100分
     2024华为OD机试题库-(C卷+D卷)-(JAVA、Python、C++) 题目描述围棋棋盘由纵横各19条线垂直相交组成,棋盘上一共19x19=361个交点,对弈双方一方执白棋,一方执黑棋,落子时只能将棋子置于交点上。“气”是围棋中很重要的一个概念,某个棋子有几口气,是指其上下左右方向四个相......
  • 程序设计与算法(三)C++:第五章poj代码
    课程:北京大学程序设计与算法(三)   MOOCOJ:OpenJudge019:全面的MyString这个题也是有很多的成员函数,我们来从主函数分析一下:MyStrings1("abcd-"),s2,s3("efgh-"),s4(s1);//无参构造,有参构造,复制可以不写 MyStringSArray[4]={"big","me","about","take"......
  • 从零开始学算法/C++/第三天
    懒标记好简单,原理就是使变化的叠加尽可能远离叶子节点,也就是说从叶子节点往根节点走,这条路径上最多只有一个地方有懒标记,要将这个懒标记尽可能远离叶子节点,拖延症了属于是,这样显然时间复杂度相较不用懒标记的要低很多。算法竞赛进阶指南里面称懒标记为延迟标记,这两种称呼都很......