基类与派生类对象的关系 派生类的构造函数

简介: 🐰 基类与派生类对象的关系 🐰派生类的构造函数

🚀🚀🚀大家觉不错的话,就恳求大家点点关注,点点小爱心,指点指点🚀🚀🚀

目录

🐰 基类与派生类对象的关系

🐰派生类的构造函数


🐰 基类与派生类对象的关系

前提引入:

公用派生类具有基类的全部功能(可以通过基类的公用成员函数访问基类的私有成员),所有基类能够实现的功能,公用派生类都能实现。而非公用派生类(私有或保护派生类)不能实现基类的全部功能。因此,基类对象与公用派生类对象之间有赋值兼容关系。

(1)公用派生类对象可以向基类对象赋值

由于公用派生类具有基类所有成员,所以把公用派生类的对象赋给基类对象

1. Person person("Marry","F",19);//定义基类Person对象person
2. //定义基类Person的公用派生类Student的对象student
3. Student student("Marry","F",19,"214210203","2021.9.1",680);
4. person=student;

注意:在赋值时时舍弃派生类新增成员,所谓的赋值只对数据成员赋值,对成员函数不存在赋值

3A4C7C9D-6EBD-4DC0-9F97-236CE91F82E8.jpeg

注意:基类对象是不能对公用派生类进行赋值,例如student=person是不存在的。因为基类成员中不包含派生类的新增成员,无法对派生类新增成员赋值,同一基类的不同派生类的对象之间也不能进行赋值。

(2)公用派生类对象可以代替基类对象向基类对象的引用进行赋值或初始化

1. Person person("Marry","F",19);
2. Student student("Marry","F",19,"214210203","2021.9.1",680);
3. //定义基类Person的对象引用personref,并用person对其初始化
4. Person &personref=person;
5. //也可以用对象student对引用personref进行初始化,将上面的语句Person &personref=person;修改为
6. Person &personref=student;
7. //或者
8. Person &personref=person;
9. personref=student;//用派生类对象student对person的引用personref赋值

22A9EE3D-243B-4829-B6C0-AF7EF7486D5F.jpeg

同样,公用派生类对象的地址可以代替基类对象地址向指向基类对象的指针进行赋值或初始化,即指向基类对象的指针也可以指向公用派生类对象。但是通过指向基类对象的指针只能访问公用派生类对象中基类成员,而不能访问公用派生类对象新增的成员。

3)如果函数参数是基类对象或基类对象的引用,相应的实参可以使用公用派生类对象。

例如:

1. void show(Person &ref)
2. {
3.     cout<<ref.show()<<endl;
4. }
5. 则调用函数show时可以使用基类Person的公用派生类对象作为实参:
6. //定义基类Person的公用派生类Student的对象student
7. Student student("Marry","F",19,"214210203","2021.9.1",680);
8. show(student);

同样,如果函数的参数是指向基类的对象的指针,相应的实参可以为公用派生类的对象的地址。

1. void show(Person *p)
2. {
3.     Cout<<p->show()<<endl;
4. }
5. 则在调用函数show时可以使用student的地址作为实参:
6. Show(&student);

 

🐰派生类的构造函数

派生类的构造函数

构造函数的作用是创建对象时对对象的数据成员进行初始化。派生类数据成员包括从基类继承过来的数据成员和自己新增加的数据成员,但是派生类并不能直接初始化从基类继承过来的数据成员,他必须使用基类的构造函数来初始化它们,在派生类构造函数的初始化列表中写出对基类构造函数的调用。

派生类的构造函数:

1. #include<iostream>
2. using namespace std;
3. class Person
4. {
5. public:
6.     Person()//无参的默认构造函数
7.     {
8.         ;
9.     }
10.     Person(string Name,string Sex,int Age):name(Name),sex(Sex),age(Age)//有参的构造函数
11.     {
12.         cout<<"The constructor of base class Person is called. "<<endl;
13.     }
14.     void show()
15.     {
16.         cout<<"The person's name:"<<name<<endl;
17.         cout<<"             sex:"<<sex<<endl;
18.         cout<<"             age:"<<age<<endl;
19.     }
20.     ~Person()//默认的析构函数
21.     {
22.         ;
23.     }
24. protected:
25.     string name;
26.     string sex;
27.     int age=0;
28. };
29. class Student:public Person//声明基类Person的公用派生类Student
30. {
31. public:
32.     Student()//无参的默认构造函数
33.     {
34.         ;
35.     }
36.     Student(string Name,string Sex,int Age,string Id,string Date,floatScore):Person(Name,Sex,Age),id(Id),date(Date),score(Score)//有参的构造函数,在初始化列表中调用基类的构造函数
37.     {
38.         cout<<"The constructor of base class Student is called. "<<endl;
39.     }
40.     void stushow()
41.     {
42.         cout<<"             student's id:"<<id<<endl;
43.         cout<<"                     name:"<<name<<endl;
44.         cout<<"                      sex:"<<sex<<endl;
45.         cout<<"                      age:"<<age<<endl;
46.         cout<<"                     date:"<<date<<endl;
47.         cout<<"                    score:"<<score<<endl;
48.     }
49.     ~Student()
50.     {
51.         ;
52.     }
53. protected:
54.     string id;
55.     string date;
56.     float score=0.0;
57. };
58. int main()
59. {
60.     Student stu("Marry","man",19,"214210203","2021.09.01",523);
61.     stu.show();
62.     stu.stushow();
63.     return 0;
64. }
65. 运行结果:
66. The constructor of base class Person is called.
67. The constructor of base class Student is called.
68. The person's name:Marry
69.              sex:man
70.              age:19
71.              student's id:214210203
72.                      name:Marry
73.                       sex:man
74.                       age:19
75.                      date:2021.09.01
76.                     score:523
Student(string Name,string Sex,int Age,string Id,string Date,floatScore):Person(Name,Sex,Age),id(Id),date(Date),score(Score)//有参的构造函数,在初始化列表中调用基类的构造函数

冒号前面是派生类Student构造函数的主干,它和以前的构造函数形式相同,但是它的总参数列表中包含着调用基类Person的构造函数所需的参数和对派生类新增的数据成员初始化所需的参数。通过冒号后面的初始化列表完成将参数传递给基类的构造函数和对派生类新增数据成员的初始化工作。

派生类构造函数的具体执行过程:

先调用基类的构造函数,对派生类对象从基类继承过来的数据成员(name,sex,age)进行初始化。接下来初始化派生类新增的数据成员(id,date,score)。最后执行派生类构造函数的函数体。

定义派生类的构造函数,以下几种情况需要注意:

(1)多级派生类的构造函数。一个类不仅可以派生出一个类,派生类还可以继续派生,形成派生的层次结构。在派生层次结构中,每一层派生类的构造函数只负责调用其上一层(即它的直接基类)的构造函数。例如,在派生类Student再派生出派生类Graduate,则派生类Gradute的构造函数如下:

1. class Gradute:public Student
2. {
3. public:
4.     Gradute()
5.     {
6.         ;
7.     }
8.     Gradute(string Name,string Sex,int Age,string Id,string Date,float Score,stringDirect,string Teacher):Student(Name,Sex,Age,Id,Date,Score),direct(Direct),teacher(Teacher)
9.     {
10.         cout<<"The constructor of base class Gradute is called. "<<endl;
11.     }
12.     void gradShow()
13.     {
14.         cout<<"             student's id:"<<id<<endl;
15.         cout<<"                     name:"<<name<<endl;
16.         cout<<"                      sex:"<<sex<<endl;
17.         cout<<"                      age:"<<age<<endl;
18.         cout<<"                     date:"<<date<<endl;
19.         cout<<"                    score:"<<score<<endl;
20.         cout<<"                   direct:"<<direct<<endl;
21.         cout<<"                  teacher:"<<teacher<<endl;
22.     }
23. protected:
24.     string direct;
25.     string teacher;
26. };

(2)当不需要对派生类新增的成员进行任何初始化操作时,此派生类构造函数的作用只是为了将参数传递给基类构造函数。

(3)如果基类中没有定义构造函数,或者定义了没有构造参数的构造函数那么在定义派生类构造函数时,在其初始化列表中可以不写对基类构造函数的调用。在调用派生类构造函数时,系统会自动调用基类的默认构造函数。

如果基类中定义了无参构造函数,又定义了有参的构造函数(构造函数的重载),则在定义派生类构造函数时,在其初始化列表中既可以包含对基类构造函数的调用,也可以不用,根据创建派生类的需求来采用哪种方式。

🌸🌸🌸如果大家还有不懂或者建议都可以发在评论区,我们共同探讨,共同学习,共同进步。谢谢大家! 🌸🌸🌸



相关文章
|
缓存 应用服务中间件 网络安全
Nginx 防止DDOS攻击
分布式拒绝服务攻击(DDoS)指的是通过多台机器向一个服务或者网站发送大量看似合法的数据包使其网络阻塞、资源耗尽从而不能为正常用户提供正常服务的攻击手段。
2831 0
快速生成软著申请时所需的60页代码文档的免费工具
本篇文章主要讲解,制作软著代码文档的高效方法,当然不可能手动一个个复制了,这显然太笨拙,他浪费时间了。这里我给大家介绍一个更快的方式。
8160 0
|
存储 JSON 前端开发
SpringMVC之JSON返回&异常处理机制(带你学习新的SpringMVC武功秘籍)
SpringMVC之JSON返回&异常处理机制(带你学习新的SpringMVC武功秘籍)
339 0
|
9月前
|
存储 监控 安全
网络安全视角:从地域到账号的阿里云日志审计实践
日志审计的必要性在于其能够帮助企业和组织落实法律要求,打破信息孤岛和应对安全威胁。选择 SLS 下日志审计应用,一方面是选择国家网络安全专用认证的日志分析产品,另一方面可以快速帮助大型公司统一管理多组地域、多个账号的日志数据。除了在日志服务中存储、查看和分析日志外,还可通过报表分析和告警配置,主动发现潜在的安全威胁,增强云上资产安全。
702 104
|
机器学习/深度学习 人工智能 计算机视觉
Meta新研究挑战CV领域基操:ViT根本不用patch,用像素做token效果更佳
【7月更文挑战第22天】Meta AI的研究颠覆了CV领域,揭示Vision Transformer (ViT) 可直接将像素视为token,无需分割成patch,此法在对象分类与图像生成等任务中表现优异,挑战现有神经网络设计,尽管面临计算效率与适用范围的质疑,仍为未来ViT模型开辟新路径。 [^1]: https://arxiv.org/abs/2406.09415
289 5
|
8月前
|
人工智能 API
DeepSeek-5min部署体验
本文介绍如何通过阿里云平台免费部署属于自己的DeepSeek AI助理,实现0成本打造满血DeepSeek。文中详细描述了创建API-KEY、下载Chatbox及配置自定义提供方的步骤,并展示了AI助理在不同场景下的表现。总结中提到,尽管部分复杂问题处理稍显卡顿,但整体准确性较高,基本满足日常需求。对于专业需求,建议探索使用自有数据集进行微调以提升性能。
201 2
|
8月前
|
运维 监控 网络协议
CURL库网页爬取:从错误处理到结果验证
CURL库网页爬取:从错误处理到结果验证
|
人工智能 关系型数据库 MySQL
一键实现穿衣自由,揭秘淘宝AI试衣间硬核技术,AnalyticDB向量在线召回
云原生数据仓库AnalyticDB MySQL为淘宝AI试衣间提供高维向量低延时的在线向量召回检索服务。
一键实现穿衣自由,揭秘淘宝AI试衣间硬核技术,AnalyticDB向量在线召回
|
缓存 安全 JavaScript
掌握JAMstack:构建更快、更安全的Web应用
JAMstack 是一种现代 Web 开发架构,结合 JavaScript、APIs 和 Markup,创建更快、更安全的 Web 应用。其核心优势包括高性能、安全性、可扩展性和易维护性。JAMstack 通过预构建静态页面和 API 实现高效渲染,利用静态站点生成器如 Gatsby 和 Next.js,并借助 CDN 和缓存策略提升全球访问速度。尽管面临复杂交互、SEO 和数据更新等挑战,但通过 Serverless Functions、预渲染和实时 API 更新等方案,这些挑战正逐步得到解决。
|
NoSQL Java Redis
利用Docker部署一个简单的springboot项目
利用Docker部署一个简单的springboot项目
374 2