继承【C/C++复习版】

目录

一、什么是继承?怎么定义继承?

二、继承关系和访问限定符?

三、基类和派生类对象可以赋值转换吗?

四、什么是隐藏?隐藏vs重载?

五、派生类的默认成员函数?

1)派生类构造函数怎么写?

2)派生类拷贝构造函数怎么写?

3)派生类operator=怎么写?

4)派生类析构函数怎么写?☆☆

六、什么是友元?友元关系能继承吗?

七、静态成员和继承的关系? 

八、什么是多继承,多继承的坑是什么?

九、如何解决菱形继承的问题? 

十、菱形虚拟继承的原理是什么?


一、什么是继承?怎么定义继承?

当多个类之间有许多共同的方法或属性时,可以将这些方法和属性提取出来作为一个父类,让子类通过继承父类来进行代码的复用,同时,子类也可以在父类的基础上做一些扩展。

怎么定义:

class 派生类名:继承方式(public/protected/private) 基类名
{
public:int _n;
};//eg:
class Student:public Person{
public:int _stuid;
};

二、继承关系和访问限定符?

1)首先对于基类的私有成员,无论以什么方式继承,在类外以及派生类内都是不可见的。

2)对于基类的公有成员保护成员

公有继承:基类所有成员保持原有访问权限。

保护继承:基类的公有成员访问权限变成保护

私有继承:基类的公有成员和保护成员访问权限变成私有

 三、基类和派生类对象可以赋值转换吗?

1)向上转换:派生类对象/指针可以赋值给基类的对象/指针/引用,这种情况也叫切片(只看到基类中的部分)。

!!注意:只有公有继承才有可能直接进行基类和派生类之间的赋值转换,私有和保护继承改变了派生类对基类的访问权限,使得无法直接进行类型转换。

2)向下转换:基类对象不能赋值给派生类对象。基类指针类型或基类引用类型如果原本是指向派生类的,那么它可以赋值给派生类指针类型或派生类引用类型,但需要手动强制类型转换。

class Base {
private:int private1;
};class Pai1 : public Base{
private:int p1;
};int main()
{Pai1 p;Base b;b = p;Base& rb = p;Base* pb = &p;Pai1* pp = (Pai1*)pb;Pai1& rp = (Pai1&)rb;
}

 四、什么是隐藏?隐藏vs重载?

在继承体系中基类和派生类的作用域是独立的,如果在基类和派生类中出现了同名成员,子类将屏蔽父类同名成员,直接访问自己的,这就叫隐藏。如果是成员函数,只要函数名相同,就构成隐藏(也叫重定义)。

如果子类想要访问父类的同名成员,可以指定类域。

class A {
public:void fun(){std::cout << "A" << std::endl;}
};
class B : public A{void fun(){A::fun();std::cout << "B" << std::endl;}
};

隐藏和重载的区别在于:隐藏是在不同的作用域的,重载是在同一作用域下的。且重载的限制条件更多,不仅要求函数同名,且形参列表必须不同。

 五、派生类的默认成员函数?

1)派生类构造函数怎么写?

派生类必须调用父类构造函数来初始化父类成员。

1)父类有默认构造,派生类构造时会自动调用父类默认构造。

2)父类没有默认构造,需要在派生类构造函数的初始列表显示调用父类构造函数。

class Person {
public:Person(string name):_name(name){}
private:string _name;
};
class Student :public Person{
public:Student(string name,int num):Person(name),_num(num){}
private:int _num;
};

2)派生类拷贝构造函数怎么写?

调用父类的拷贝构造,可以传子类的对象给父类拷贝构造,构成切片。然后再实现自己的部分。

不显示写的话会调父类的默认构造而不是拷贝构造,所以不能不显示调用。

	Student(const Student& stu):Person(stu),_num(stu._num){}

3)派生类operator=怎么写?

 要显示调用父类的operator=,再实现自己的部分。

	Student& operator=(const Student& stu){if (this != &stu) {Person::operator=(stu);//调用父类的_num = stu._num;}return *this;}

4)派生类析构函数怎么写?☆☆

 派生类的析构函数不需要我们手动调用,因为它要保证先析构子类,再析构父类。以防出现析构完父类后,子类又用到父类成员的情况。让编译器来做这件事比让人来做更靠谱。

六、什么是友元?友元关系能继承吗?

如果一个函数或一个类想访问某一个类A的保护成员或私有成员,可以在类A中声明一下:

 注意:友元关系不能继承!!!

七、静态成员和继承的关系? 

静态成员不属于某个类或对象,它是在静态区中保存的,只有一份,但它是受类的访问限定符的约束的。子类继承的是静态成员的使用权。

静态成员变量必须在类内声明,类外定义和初始化

静态成员函数的定义和初始化可以在类内也可以在类外。

class MyClass {
public:static int staticVar; // 在类内声明静态成员变量static void staticFunc() {// 在类内定义静态成员函数,可以直接实现功能}
};int MyClass::staticVar = 0; // 在类外定义静态成员变量并进行初始化

八、什么是多继承,多继承的坑是什么?

一个人是可能有多重角色的,那么有多个父类也是合理的。

但是,有了多继承,就有可能出现菱形继承,菱形继承会引发很多问题:

① 二义性(Assistant对象中访问的_name到底访问的是从哪个类中继承的?)

② 数据冗余(浪费空间)

九、如何解决菱形继承的问题? 

1)二义性:可以通过指定类域来访问,这种方式虽然表面上解决了二义性的问题,但它其实是违背了现实世界的。

2)更根本地解决数据冗余和二义性的做法是:虚继承

给菱形继承中继承了同一个类的类都加上virtual关键字。

class Student:virtual public Person
{//...
}
class Teacher:virtual public Person
{//...
}

十、菱形虚拟继承的原理是什么?

继承了同一个类的这些类加了virtual关键字后,这些类会多一个成员,这个成员的类型是虚基表的指针,指向的是一张虚基表,虚基表里保存是距离父类的成员的偏移量。

思考一下:D对象赋值给B对象的切片,B*pb = &d; pb->_a可以正常访问吗?

为什么不直接存偏移量?

虚基表除了存偏移量可能还会存别的值,在对象中存虚基表的指针可以保证每个对象只需要多存一个指针大小即可。

在下面的例子中,A的构造会调用几次?ABCD谁先构造?

十一、继承和组合的区别?什么时候用继承,什么时候用组合?

组合是指一个类持有另一个类的实例作为自己的属性,通过调用被组合对象的方法实现功能。组合是一种"has a"关系,即一个对象包含另一个对象。

在选择使用继承还是组合时,通常遵循以下原则:

- 当两个类之间有明显的"is a"关系,即子类是父类的一种特殊形式时,可以使用继承。

- 当两个类之间有“has a”关系,即一个类包含另一个类作为属性时,可以使用组合。

继承时一种白箱复用,其内部的细节对子类是可见的,组合是一种黑箱复用,对象内部细节是不可见的。尽量避免过度使用继承,因为过度继承可能导致类之间的耦合度过高,影响代码的灵活性和可维护性。因此在设计时需要根据具体的情况选择合适的方式来设计类之间的关系。

 

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

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

相关文章

关于转义符 \ 在php正则中的匹配问题

今天做题遇到一个很经典的问题&#xff0c;记录一下&#xff0c;先看一段代码 <?php $str&#xff0c;&#xff0c;"\\"; $pattern&#xff0c;&#xff0c;"/\\/"; if(preg_match($partern,$str,$arr)) { &#xff0c;&#xff0c;&#xff0c;&…

Qt QString类

数值输入 C 提供了两种字符串的实现方式&#xff1a;一种是C风格的字符串&#xff0c;以“0”结尾&#xff1b;另一种是 C引入的 String 类型&#xff0c;即标准模板库中的类。Qt则提供了自己的字符串实现方式——QString。 Qt中的QString字符串类&#xff1a; 无须担心…

如何使用設置Python代理IP?

本文旨在探討Python代理IP、使用Python代理伺服器的好處、如何安裝 Python代理以及如何用Python設置代理IP伺服器。 什麼是Python代理伺服器&#xff1f; 用Python實現的代理IP模式&#xff0c;可用於延遲加載、日誌記錄、訪問控制或其他目的。 Python的動態類型和豐富的類支持…

SpringBoot编写一个SpringTask定时任务的方法

1&#xff0c;在启动类上添加注解 EnableScheduling//开启定时任务调度 2&#xff0c; 任务&#xff08;方法&#xff09;上也要添加注解&#xff1a; Scheduled(cron " 0 * * * * ? ") //每分钟执行一次 域&#xff1a; 秒 分 时 日 月 周 &#xff08;年&#…

如何修复在Deepin系统中因`apt-get autoremove systemd`导致的启动问题

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

选择正确的Go Module Path

最近我在查看项目代码时&#xff0c;注意到有人在go.mod文件中将module path写为com.example.foo了。根据这个写法&#xff0c;相信屏幕前的读者也可以推断出这位开发人员可能是从Java阵营转到Go的。实际开发中可能有很多开发者会使用类似的内容作为module path&#xff0c;但这…

Redis和Mysql如何保证数据一致性?

一份数据同时保存在数据库和Redis中&#xff0c;当数据发生变化时需要同时去更新Mysql和Redis&#xff0c;由于这个更新有先后顺序并且它不像Mysql里面的多表事物一样可以满足ACID的事物特性&#xff0c;所以就会出现数据一致性的问题。 对于这种情况解决方案主要有以下几种&a…

Jmeter针对多种响应断言的判断

有时候response返回的结果并非一种&#xff0c;有多种&#xff0c;需要对这几种进行判断的时候需要使用Bean Shell。 &#xff08;1&#xff09;首先获取响应数据 String response prev.getResponseDataAsString(); ResponseCode 响应状态码 responseHeaders 响应头信息 res…

Peter算法小课堂—动态规划斜率优化

大家来到这一堂课&#xff0c;就说明大家已经学过函数了 直线方程&#xff1a;ykxb 大家可以算一算。 其实&#xff0c;在数学上&#xff0c;这玩意要分类讨论 那么&#xff0c;这唯一的交点就是我们要背出来的 直线最值 这像一个分段函数 其实&#xff0c;只有部分直线能提供…

支付牌照7000万出让:成都摩宝以1.29亿挂牌价出让60.33% 股份

重庆中渝兴拍科技有限公司受重庆力帆控股有限公司委托于2024年04月26日10时至2024年04月27日10时止在淘宝网阿里资产交易平台对力帆持有成都摩宝网络科技有限公司60.332806%股权转让进行公开拍卖活动&#xff0c;起始价为129,000,000元。 相关情况如下&#xff1a; 成都摩宝网…

docker-compose yaml指定具体容器网桥ip网段subnet

docker-compose 启动yaml有时可能的容器网段与宿主机的ip冲突导致宿主机上不了网&#xff0c;这时候可以更改yaml指定subnet 宿主机内网一般是192**&#xff0c;这时候容器可以指定172* version: 3.9 services:coredns:image: coredns/coredns:1.10.0container_name: coredns…

详解Qt添加外部库

在Qt项目中添加外部库是一项常见任务&#xff0c;无论是静态库还是动态库都需要正确的配置才能让项目顺利编译链接。以下是详细步骤和不同场景下的配置方法&#xff1a; 方法一&#xff1a;手动编辑.pro文件 添加头文件路径&#xff1a; 在Qt项目中的.pro文件中使用INCLUDEPAT…

IO_DAY7

1:实现2个终端之间的互相聊天 要求:千万不要做出来2个终端之间的消息发送是读一写的&#xff0c;一定要能够做到&#xff0c;一个终端发送n条消息&#xff0c;另一个终端一条消息都不回复都是没有问题的 终端A&#xff1a; #include<myhead.h> int main(int argc, char…

【YOLOv9改进[损失函数]】使用结合InnerIoU和Focaler的各种损失函数助力YOLOv9更优秀

目录 一 回归损失函数&#xff08;Bounding Box Regression Loss&#xff09; 1 Inner-IoU 2 Focaler-IoU&#xff1a;更聚焦的IoU损失 二 改进YOLOv9的损失函数 1 总体修改 ① utils/metrics.py文件 ② utils/loss_tal_dual.py文件 2 各种机制的使用 ① 使用结合Inn…

ActiveMQ 02 常用API

Active MQ 02 常用API 事务 session.commit(); session.rollback();用来提交/回滚事务 Purge 清理消息 签收模式 签收代表接收端的session已收到消息的一次确认&#xff0c;反馈给broker ActiveMQ支持自动签收与手动签收 Session.AUTO_ACKNOWLEDGE 当客户端从receive…

【01背包】滚动数组优化实现一维01背包DP(对比朴素写法)

01背包 代码 背包问题的滚动数组优化版本建议在完全弄懂了普通的二维01背包问题后再进行食用&#xff0c;不然会出现消化不良的症状… 我们可以将背包问题中DP数组的下标看作成两个集合 下面对比两种不同实现方法的区别&#xff1a; 朴素二维DP版本 使用dp[不超过i的物品集合]…

全量知识系统 程序详细设计 之 三种“活物” 之1(QA百度文库 )

Q1. 今天聊聊 全知系统中 三种“活物”。先从他们的一个简单描述开始&#xff1a;自主&#xff1a;计算机“集群”的“沉”与“浮”自然&#xff1a;AI “众生”的“世”和“界”自由&#xff1a;人类 “公民”的“宇”或“宙” 这是一个非常有趣且深刻的主题&#xff0c;将全…

2024年MCN商业模式运营体系行业发展分析

【干货资料持续更新&#xff0c;以防走丢】 2024年MCN商业模式运营体系行业发展分析 部分资料预览 资料部分是网络整理&#xff0c;仅供学习参考。 mcn运营资料包&#xff08;完整资料包含以下内容&#xff09; 目录 MCN机构运营方案的概要&#xff1a; 一、MCN机构定位与目…

关于java分页功能以及传参规范

不用插件 //当前页码private static final Integer currentPage 2;//设置每页个数private static final Integer pageSize 5;Testpublic void test8() {//手写一个分页测试&#xff0c;不用插件List<Integer> list new ArrayList<>(Arrays.asList(1,2,3,4,5,6,7…

Docker 国内镜像

Docker 国内镜像 安装好Docker/Docker Desktop后&#xff0c;其registry server是默认指向https://hub.docker.com的。在国内该hub源访问速度异常慢&#xff0c;可以通过切换至国内镜像仓库来解决这一问题。 sudo vi /etc/docker/daemon.json 添加以下内容&#xff1a; { “re…