【友元补充】【动态链接补充】

友元

友元的目的是让一个函数或者类,访问另一个类中的私有成员。

有缘的关键字friend是一个修饰符。

友元分为友元类和友元函数

1.全局函数作友元

2.类作友元

3.类的一个成员函数作友元

好处:可以通过友元在类外访问类内的私有和受保护类型的成员

坏处:破坏了类的封装性

class A {int num_a;
public:friend void fun();friend class B;
};
void fun() {A a;a.num_a = 2;cout << a.num_a << endl;
}
class B {
public:void fun() {A a;a.num_a = 2;cout << a.num_a << endl;}
};
int main() {fun();B b;b.fun();return 0;
}

 通过自行运行,我们可以看到结果如预期结果一致。

现在对于第三种情况进行单独讲解补充:

class B{
public:void work(){A a;a.num=3;};
};
class A{friend void  B::work(); //只让类内的某一个成员函数成为类A的友元函数int num;
};

当你把它看进去的时候,恭喜你,错了。此时a.num访问权限有问题。因为在这里A还没有将B的这个成员函数作为友元函数,A没有权限访问A类的私有成员。

class B{
public:void work();
};
class A{friend void  B::work(); //只让类内的某一个成员函数成为类A的友元函数int num;
};
void B::work() {A ma;ma.num = 3;
}

此时我们可以通过类外实现成员函数解决上述问题。而且类外实现的位置,必须在A将B的成员函数设为友元后。否则依然会报错。


 动态绑定

【⚪】成员函数必须声明为virtual

【⚪】如果基类中声明了为虚函数,则派生类中重写的函数不必再用virtual修饰

         调用方式:通过对象的指针或引用调用成员函数,或通过成员函数调用,反之就无法实现动态链接。

        特点:灵活,问题抽象性和问题的易维护性。

class A {int m_data1, m_data2;
public:virtual void vfunc1();virtual void vfunc2();void func1();void func2();
};
class B :public A {int m_data3;
public:virtual void vfunc1();void func1();
};
class C :public B {int m_data1, m_data4;
public:virtual void vfunc2();void func2();
};
类A、B、C的对象模型

利用终端查看:

 

图解分析: 

【⚪】由于这三个类都有虚函数,故编译器为每个类都创建了一个虚表,即类 A 的虚表(A vtbl),类B的虚表(B vtbl),类 C的虚表(C vtbl)。类 A,类 B,类 C 的对象都拥有一个虚表指针,*vptr,用来指向自己所属类的虚表。
【⚪】类 A 包括两个虚函数,故 A vtbl 包含两个指针,分别指向 A::vfunc1()和A::vfunc2()。

【⚪】类 B 继承于类 A,故类 B 可以调用类 A 的函数,但由于类 B 重写了B::vfunc1()函数,故 B vtbl 的两个指针分别指向 B::vfunc1()和 A::vfunc2()。

【⚪】类 C 继承于类 B,故类 C 可以调用类 B 的函数,但由于类 C 重写了C::vfunc2()函数,故 C vtbl 的两个指针分别指向 B::vfunc1()(指向继承的最近的一个类的函数)和C::vfunc2()。
【⚪】虽然模型看起来有点复杂,但是只要抓住“对象的虚表指针用来指向自己所属类的虚表,虚表中的指针会指向其继承的最近的一个类的虚函数”这个特点,便可以快速将这几个类的对象模型在自己的脑海中描绘出来。
【⚪】非虚函数的调用不用经过虚表,故不需要虚表中的指针指向这些函数。

假设我们定义一个类 B 的对象。由于 bObject是类 B 的一个对象,故 bObject包含一个虚表指针,指向类 B 的虚表。

int main(){B bObject;return 0;
}

现在,我们声明一个类 A 的指针p来指向对象 bObject。虽然p是基类的指针只能指向基类的部分,但是虚表指针亦属于基类部分,所以p可以访问到对象 bObject的虚表指针。bObiect的虚表指针指向类 B的虚表,所以p可以访问到 Bvtbl。 

int main(){B bObject;A* p=&bObject;//父类指针指向子类对象return 0;
}

 当我们使用p来调用vfunc1()函数时,会发生什么现象?

int main(){B bObject;A* p=&bObject;p->vfunc1();return 0;
}

 程序在执行 p->vfunc1()时,会发现p是个指针,且调用的函数是虚函数,接下来便会进行以下的步骤。
        首先,根据虚表指针 p->vptr来访问对象 bObject 对应的虚表。虽然指针p是基类 A 类型,但是 vptr 也是基类的一部分,所以可以通过 p->vptr 可以访问到对象对应的虚表
        然后,在虚表中查找所调用的函数对应的条目。由于虚表在编译阶段就可以构造出来了,所以可以根据所调用的函数定位到虚表中的对应条目。对于p->vfunc1()的调用,B vtbl 的第一项即是 vfunc1 对应的条目。
        最后,根据虚表中找到的函数指针,调用函数。从图3可以看到,Bvtbl的第一项指向 B::vfunc1(),所以 p->vfunc1()实质会调用 B::vfunc1()函数。

 

class A{
public:virtual void vfun1(){cout<<"father eat"<<endl;}
};
class B:public A{    
public:virtual void vfun1()//在继承关系下,vfun1前面不写virtual,它也是虚函数{cout<<"child eat"<<endl;}
};
int main(){A *a=new B;a->vfun1();return 0;
}

感谢大家支持,今日份知识点已经补充完毕。

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

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

相关文章

CC面试准备

半导体基础 半导体是介于导体和绝缘体之间的一种介质&#xff0c;在不同条件下表现出不同的导电性或者不导电特性&#xff0c; 电子半导体器件材料大部分为硅&#xff0c;锗等元素 本征半导体&#xff1a;完全不含杂质的纯净半导体&#xff0c;因为不含杂质&#xff0c;其中…

使用API有效率地管理Dynadot域名,设置域名服务器(NS)

前言 Dynadot是通过ICANN认证的域名注册商&#xff0c;自2002年成立以来&#xff0c;服务于全球108个国家和地区的客户&#xff0c;为数以万计的客户提供简洁&#xff0c;优惠&#xff0c;安全的域名注册以及管理服务。 Dynadot平台操作教程索引&#xff08;包括域名邮箱&…

OCR识别系统 YOLOv8 +Paddle 方案落地

YOLOv8 PaddleOCR 技术方案落地 Yolov8相关文档Step 1 证件模型的训练Step 2 Yolov8进行图片推理Step 3 PaddleOCR进行识别Step 4 整合Yolov8 PaddleOCR 进行OCR Yolov8相关文档 《yolov8 官方网站》 《Yolov8 保姆级别安装》 Ultralytics YOLOv8 是一款尖端的、最先进的 (S…

【项目经验分享】深度学习自然语言处理技术毕业设计项目案例定制

以下毕业设计是与深度学习自然语言处理&#xff08;NLP&#xff09;相关的毕业设计项目案例&#xff0c;涵盖文本分类、生成式模型、语义理解、机器翻译、对话系统、情感分析等多个领域&#xff1a; 实现案例截图&#xff1a; 基于深度学习的文本分类系统基于BERT的情感分析系…

《AI大模型工程师》报考都学习哪些内容呢?

近年来&#xff0c;随着深度学习技术的迅猛发展&#xff0c;AI大模型已经成为人工智能领域的重要研究方向和热点话题。AI大模型&#xff0c;指的是拥有巨大参数规模和强大学习能力的神经网络模型&#xff0c;如BERT、GPT等&#xff0c;这些模型在自然语言处理、计算机视觉等领域…

Vue项目快速整合WangEditor富文本编辑器

Vue项目快速整合WangEditor富文本编辑器 一、安装依赖 npm i wangeditor --save //富文本编辑器 npm install highlight.js -S //代码高亮 npm install dompurify vue-dompurify-html // 防xss 库二、app.vue代码案例 已对接图片、视频接口 &#xff0c;具体看如下代码…

使用canvas截取web camera指定区域,并生成图片

目标&#xff0c;截取红色色块背后的视频区域。 代码结构如下&#xff1a; <div id"p1"><video id"v1" autoplay playsinline></video><div id"mrz"></div><canvas id"captureCanvas"></can…

小程序开发设计-小程序的宿主环境:宿主环境简介⑥

上一篇文章导航&#xff1a; 小程序开发设计-小程序代码的构成&#xff1a;小程序页面的组成部分详解⑤-CSDN博客https://blog.csdn.net/qq_60872637/article/details/142306902?spm1001.2014.3001.5501 注&#xff1a;不同版本选项有所不同&#xff0c;并无大碍。 目录 上…

【C++】模板、宏、命名空间、

十五、C中的模板templates 本部分讨论C中的模板templates 在别的语言中&#xff0c;比如java、c、c#等托管语言中&#xff0c;模板类似泛型的概念&#xff0c;但模板比泛型要强大得多。模板有点像宏&#xff0c;而泛型却非常受限于类型系统以及其他很多因素。同时模板也是一个…

腾讯云SDK基本概念

本文旨在介绍您在使用音视频终端 SDK&#xff08;腾讯云视立方&#xff09;产品过程中可能会涉及到的基本概念。 音视频终端 SDK&#xff08;腾讯云视立方&#xff09; 应用 音视频终端 SDK&#xff08;腾讯云视立方&#xff09;通过应用的形式来管理您的项目&#xff08;Ap…

net core mvc 数据绑定 《1》

其它的绑定 跟net mvc 一样 》》MVC core 、framework 一样 1 模型绑定数组类型 2 模型绑定集合类型 3 模型绑定复杂的集合类型 4 模型绑定源 》》》》 模型绑定 使用输入数据的原生请求集合是可以工作的【request[],Querystring,request.from[]】&#xff0c; 但是从可读…

【一文读懂】C#如何实现通用的排序功能

目录 通用排序功能 1.升序 2.降序 测试 1.测试代码 2.测试结果 本篇文章来分享一下C#如何实现通用的排序功能。在项目中经常会使用到排序的方法&#xff0c;那如何使排序方法更加通用呢&#xff1f;可以通过泛型&#xff0c;接口&#xff0c;委托来实现。 通用排序功能…

学校周赛(1)

A - Short Sort 题目&#xff1a; 思路&#xff1a; 本条题目只允许改一处地方&#xff0c;只有三个字母&#xff0c;我们可以直接枚举所有移动过的结果&#xff0c;同时使用哈希去记录其值&#xff0c;对于每一个输入我们都寻找是否有这个值记录&#xff0c;有则输出YES否则…

数据结构与算法——Java实现 19.队列

目录 一、概述 二、链表实现队列 接口定义 接口实现类 测试类 三、环形数组实现队列 优点 下标计算 判满和判空 判满 判空 辅助变量size判空和判满 方法1 接口定义 接口实现类 测试类 方式2 接口定义 接口实现类 测试类 方法3 接口定义 接口实现类 测试类 生活鲜少给人留下退…

项目实战:构建高效可扩展的Flask Web框架:集成Flask-SQLAlchemy、Marshmallow与日志管理

前言 在Web开发中&#xff0c;构建一个既高效又可扩展的框架是项目成功的基石。Flask作为一个轻量级的Web应用框架&#xff0c;凭借其易用性和灵活性&#xff0c;特别适合快速开发和原型设计。结合Flask-SQLAlchemy&#xff08;为Flask提供SQLAlchemy ORM支持的扩展&#xff0…

剑指 offer 刷题集

目录 数组 1. LCR 121. 寻找目标值 - 二维数组 2. LCR 120. 寻找文件副本 3. LCR 128. 库存管理 I 4. LCR 131. 砍竹子 I 5. LCR 132. 砍竹子 II 6. LCR 135. 报数 7. LCR 139. 训练计划 I 8. LCR 158. 库存管理 II 9. LCR 159. 库存管理 III 10. LCR 160. 数据流中…

计算机毕业设计 在线项目管理与任务分配系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

一文带你读懂分库分表,分片,Sharding的许多概念

一文带你读懂分库分表,分片,Sharding的许多概念 分库是将一个库拆分为多个库&#xff0c;分表就是将一个表拆分为多个表。分库分表有垂直拆分和水平拆分。垂直拆分一般是按照业务将表分到不同的库中&#xff08;此种不在本发的讨论范围&#xff09;。水平拆分是将表的数据拆分…

HEITRONICS TC13红外辐射高温计CT13 INFRARED RADIATION PYROMETER CT13

HEITRONICS TC13红外辐射高温计CT13 INFRARED RADIATION PYROMETER CT13

华为玄玑感知系统震撼发布:智能穿戴新品引领情绪健康新纪元

在科技日新月异的今天&#xff0c;华为再次以其卓越的创新能力&#xff0c;为智能穿戴领域带来了一场革命性的变革。 8月28日&#xff0c;华为玄玑感知系统暨穿戴创新技术发布会圆满落幕&#xff0c;会上正式揭晓了这款名为“玄玑”的神秘感知系统&#xff0c;预示着穿戴设备将…