从0开始C++(七):继承

news2024/11/8 12:26:57

相关文章:

从0开始C++(一):从C到C++

从0开始C++(二):类、对象、封装

从0开始C++(三):构造函数与析构函数详解

从0开始C++(四):作用域限定符、this指针、static与const关键字

从0开始C++(五):友元函数&运算符重载

从0开始C++(六):模板与容器的使用

目录

继承

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

委托构造

继承构造

多重继承

虚继承


继承

继承是一种面向对象的编程特性,允许一个类(称为子类或派生类)从另一个类(基类或父类)继承属性和方法。通过继承,子类可以获得基类的成员变量和成员函数,并且可以添加自己的特定实现。

C++中的继承有以下几种类型:

  1. 公有继承(public inheritance):在派生类中,基类的公有成员在派生类中仍然是公有的,基类的保护成员在派生类中变为保护的,基类的私有成员在派生类中不可访问。

  2. 保护继承(protected inheritance):在派生类中,基类的公有和保护成员在派生类中都变为保护的,基类的私有成员在派生类中不可访问。

  3. 私有继承(private inheritance):在派生类中,基类的公有和保护成员在派生类中都变为私有的,基类的私有成员在派生类中不可访问。

类内

派生类

全局

private

×

×

protected

×

public

 在使用继承时,可以使用关键字 public  protected private 指定继承的类型。默认情况下,继承是公有的。

继承还可以用于实现多态性(polymorphism)。C++中的多态性允许通过基类的指针或引用来调用派生类的成员函数。这种特性可以方便地实现代码的重用和扩展。

下面是一个简单的C++继承的示例:

#include <iostream>

using namespace std;

class Animal {
public:
    void eat() {
        cout << "Animal is eating." << endl;
    }
};

class Dog : public Animal {
public:
    void bark() {
        cout << "Dog is barking." << endl;
    }
};

int main() {
    Dog dog;
    dog.eat(); // 继承自基类Animal的eat()函数
    dog.bark(); // 子类Dog自己的函数
    return 0;
}

输出结果为:

Animal is eating.
Dog is barking.

在上述示例中,Dog类继承自Animal类,并且可以调用Animal类中的成员函数eat(),同时还具有自己的成员函数bark()。

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

派生类和基类之间有一定的关系,包括构造函数。当创建派生类的对象时,首先会调用基类的构造函数,然后再调用派生类的构造函数。

派生类可以通过以下两种方式来调用基类的构造函数:

1、默认方式:如果在派生类的构造函数中没有显式调用基类的构造函数,则会默认调用基类的默认构造函数。如果基类没有默认构造函数,派生类的构造函数将无法编译通过。

class Base {
public:
    Base() {
        cout << "Base constructor" << endl;
    }
};

class Derived : public Base {
public:
    Derived() {
        cout << "Derived constructor" << endl;
    }
};

int main() {
    Derived d;
    return 0;
}

输出结果为:

Base constructor
Derived constructor

2、显式调用(透传构造):派生类的构造函数可以显式调用基类的构造函数,通过使用初始化列表来实现。

class Base {
public:
    Base(int x) {
        cout << "Base constructor with parameter: " << x << endl;
    }
};

class Derived : public Base {
public:
    Derived(int y) : Base(y) {
        cout << "Derived constructor with parameter: " << y << endl;
    }
};

int main() {
    Derived d(10);
    return 0;
}

输出结果为:

Base constructor with parameter: 10
Derived constructor with parameter: 10

需要注意的是,在派生类的构造函数中,应该按照继承层次从上到下调用基类的构造函数。并且每个构造函数只能直接调用其直接基类的构造函数,而不能调用其间接基类的构造函数。否则会导致编译错误。

另外,无论是默认方式还是显式调用,基类的构造函数都会在派生类的构造函数中被调用,以确保基类的成员变量和成员函数被正确初始化。

委托构造

C++11引入了委托构造的概念,允许一个构造函数直接调用另一个构造函数。委托构造函数可以简化代码并减少冗余。

使用委托构造函数的方式:

使用构造函数的初始化列表来调用其他构造函数。

class MyClass {
public:
    MyClass(int x, int y) : a(x), b(y) {
        // 其他初始化操作
    }
    
    MyClass(int x) : MyClass(x, 0) {
        // 其他初始化操作
    }

private:
    int a;
    int b;
};

在上述示例中,第一个构造函数接受两个参数,第二个构造函数只接受一个参数。通过在第二个构造函数的初始化列表中调用第一个构造函数,可以避免重复编写初始化操作。

需要注意的是,委托构造函数的调用顺序必须满足构造函数的初始化列表顺序,以确保对象的成员变量正确初始化。另外,委托构造函数不能形成递归调用,即构造函数之间不能形成循环委托

继承构造

C++11新增写法只需要一句话就可以自动派生类添加n构造函数(n为基类构造函数的个数)。并且每个派生类构造函数格式都与基类相同每个派生类构造函数都通过透传构造调用对应格式基类构造函数
// 只加这一句,编译器就会自动添n个构造函数,Father为基类名称
    using Father::Father;

实例

#include <iostream>
#include <map>

using namespace std;

// 基类
class Father
{
private:
    string name;
public:
    Father():name("张"){}
    // 有参构造函数
    Father(string name):name(name){}
    string get_name()
    {
        return name;
    }
};

// 派生类继承基类
class Son:public Father // public继承,权限保持不变
{
public:
    // 只加这一句,编译器就会自动添加下面两种构造函数
    using Father::Father;

//    Son():Father(){}

//    Son(string fn):Father(fn){}

};

int main()
{
//    Son son;
    Son son("王");
    cout << son.get_name() << endl;

    return 0;
}

多重继承

多重继承,即一个派生类可以同时继承多个基类。多重继承的语法形式如下:

class Derived : public Base1, public Base2, ... {
    // 派生类的成员和函数
};

在上述示例中,Derived是一个派生类,继承了Base1Base2两个基类。通过逗号分隔,可以继承更多的基类。

派生类继承多个基类后,可以访问各个基类的成员变量和成员函数,以及自己定义的成员变量和成员函数。

当派生类中有与基类同名的成员时,可以通过作用域解析符::来指定要访问的成员属于哪个基类

虚继承

另外,C++中还存在虚继承的概念。虚继承用于解决多重继承中的菱形继承问题(即一个派生类继承了多个共同的基类)以及相关的二义性问题。虚继承可以通过在基类之间添加 virtual 关键字来实现。具体的虚继承语法如下:

class Base1 {
    // 基类1的成员
};

class Base2 {
    // 基类2的成员
};

class Derived : public virtual Base1, public virtual Base2 {
    // 派生类的成员
};

在虚继承中,派生类通过 virtual 关键字进行基类的声明,以确保只有一个实例的共同基类。这样就可以避免菱形继承和二义性问题。 

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

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

相关文章

香港服务器托管对外贸行业必要性和优势

在当今全球化的经济环境下&#xff0c;外贸企业面临着前所未有的机遇与挑战。其中&#xff0c;服务器托管的选择对于外贸企业的运营效率和市场拓展具有举足轻重的作用。香港服务器&#xff0c;凭借其独特的地理位置、优质的网络环境和卓越的服务性能&#xff0c;一直是外贸企业…

2024年必备的15个免费 SVG 设计资源

在动态设计领域&#xff0c;SVG&#xff08;可缩放矢量图形&#xff09;已成为设计师打造响应迅速、清晰且适应性强的视觉效果的必备工具。 这些设计非常适合幻灯片 PowerPoint 演示文稿、应用程序设计、网站设计、原型设计、社交媒体帖子等。 在这篇文章中&#xff0c;我们将…

这份AI绘画攻略赶紧码住!超适合小白入门的PS AI插件来啦!

有没有小伙伴对AI绘画很感兴趣&#xff0c;但是看到国外的mj和sd总觉得入门困难&#xff01;别担心&#xff0c;米兔挖到一款超级绝的国产PS AI插件&#xff01;适合新手学习&#xff0c;米兔这里还有一份专为小白准备的AI绘画攻略&#xff0c;让你的创意不再受限&#xff01; …

评测|贪吃小猫疯狂长肉,让它停不下嘴的希喂、鲜朗、帕特真实调研

我发现很多铲屎官存在一个误区&#xff0c;认为“进口即是高贵”&#xff0c;过度信赖进口产品。一见到进口宠物粮就冲动购买&#xff0c;甚至对国产品牌持贬低态度&#xff0c;贴上“质量不佳”、“不符合标准”等标签。 为了更深入地了解这一现象&#xff0c;我深入研究了主食…

minio+tusd+uppy搭建文件上传服务

1、docker部署minio、tusd服务 1.1 新建docker-compose.yml minio API: http://ip:9100 minio控制台: http://ip:9101 tus API: http://ip:9102/files/ tus webhooh: http:172.0.0.1:3000/files/webhooh(用户鉴权API) version: 3.7services:minio:image: minio/minio:RELEAS…

工业软件的分类与选择策略:针对中小企业的实际应用考量

工业软件是现代工业体系的“大脑”&#xff0c;已经渗透到几乎所有工业领域的核心环节&#xff0c;是现代产业之“魂”&#xff0c;是制造强国之重器。工业软件通过优化生产流程、实时监控设备状态、实现自动化控制等功能&#xff0c;可以帮助企业显著提升生产效率和质量&#…

python爬虫-爬虫的基础知识储备

爬虫就是一个不断的去抓去网页的程序&#xff0c;根据我们的需要得到我们想要的结果&#xff01;但我们又要让服务器感觉是我们人在通过浏览器浏览不是程序所为&#xff01;归根到底就是我们通过程序访问网站得到html代码&#xff0c;然后分析html代码获取有效内容的过程。下面…

透明屏幕的魅力:为何它如此受欢迎

在科技日新月异的今天&#xff0c;透明屏幕技术以其独特的魅力和广泛的应用前景&#xff0c;逐渐成为了科技领域的一颗璀璨明星。从智能手机、平板电脑到大型显示屏&#xff0c;透明屏幕技术以其前所未有的视觉体验和实用性&#xff0c;赢得了广大消费者的喜爱。 一、透明屏幕的…

苏宁易购通用卡怎么使用?

现在还有人用苏宁的礼品卡吗 前两天618&#xff0c;想买点家电&#xff0c;但是在苏宁上看价格还不如京东淘宝优惠 最后手里的苏宁卡也没用出去 本来想着要不送人算了&#xff0c;但是收卡云的价格也还不错&#xff0c;最后就卖出去了 500块钱的苏宁卡买了475&#xff0c;到…

麦汁充氧装置——文丘里管

嗨&#xff0c;亲爱的酿酒师们&#xff01;今天&#xff0c;小编要来给大家介绍一个在啤酒酿造中起关键作用的装置——文丘里管&#xff0c;诚挚地邀请各位朋友们&#xff0c;与天泰一起探讨文丘里管的工作原理以及其在精酿啤酒领域的应用。 大家都知道&#xff0c;酵母属于兼性…

DIY 智能门禁:用 ESP32 RFID 打造安全便捷的家居体验 (附代码)

一、系统概述 本项目旨在使用 ESP32 微控制器和 RFID 技术构建一个安全可靠的门禁系统。该系统利用 RFID 卡进行身份验证&#xff0c;通过读取卡内存储的唯一 ID&#xff0c;判断用户权限并控制门锁的开关。ESP32 强大的 Wi-Fi 功能还能实现远程监控和管理&#xff0c;方便用户…

系统漏洞复现与勒索病毒

知识点&#xff1a;SMB漏洞介绍、漏洞复现流程、勒索病毒攻击与防护 渗透测试相关&#xff1a; 基本概念&#xff1a; 渗透测试就是利用我们所掌握的渗透知识&#xff0c;对网站进行一步一步的渗透&#xff0c;发现其中存在的漏洞和隐藏的风险&#xff0c;然后撰写一篇测试报…

[经典]原型资源:蚂蚁金服UI模版部件库

部件库预览链接&#xff1a; https://d3ttsx.axshare.com 支持版本: Axrure RP 8 文件大小: 30MB 文档内容介绍 基本部件&#xff1a;表单样式&#xff1a;12款、数据样式&#xff1a;10款、服务样式&#xff1a;6款、导航&#xff1a;5款、业务组件&#xff1a;7款、 模板…

TMDS编码原理以及Verilog实现HDMI接口

文章目录 一、HDMI简介二、HDMI接口以及引脚定义三、HDMI传输原理四、TMDS编码规则以及实现4.1 TMDS编码框图4.2 TMDS编码流程图4.3 Verilog实现TMDS编码 五、OSERDESE2原语介绍以及使用5.1 OSERDESE2内部框图5.2 OSERDESE2 输入输出管脚信号说明5.3 OSERDESE2 配置属性信号说明…

如何写好AI绘画提示词?保姆级教程来了!

前言 提示词编辑是一个结构化的过程&#xff0c;用能被人类解释和理解的词语来描述图像&#xff0c;也就是告诉人工智能模型应该怎么绘制图片。 生成优质图像的秘诀 1.提示词要想编辑好&#xff0c;包括修饰词和好的句子结构&#xff0c;首先你要了解所有的修饰词类型。 2.St…

浅析Kubernetes的权限控制模型

Kubernetes是一个开源的容器编排引擎&#xff0c;用来对容器化应用进行自动化部署、扩缩和管理。它是一个强大的集群管理系统&#xff0c;提供了丰富的功能。他的一个核心组件是Kubernetes API Server&#xff0c;这是集群中所有资源管理的入口点&#xff0c;提供了一组RESTful…

【算能全国产AI盒子】基于BM1688CV186AH+FPGA智能物联工作站,支持差异化泛AI视觉产品定制

在数据呈现指数级增长的今天&#xff0c;越来越多的领域和细分场景对实时、高效的数据处理和分析的需求日益增长&#xff0c;对智能算力的需求也不断增强。为应对新的市场趋势&#xff0c;凭借自身的硬件研发优势&#xff0c;携手算能相继推出了基于BM1684的边缘计算盒子&#…

可视化大屏的C位:12种常见的情形,一文告诉你。

C位又称焦点图&#xff0c;是占据可视化大屏视觉焦点位置&#xff0c;一般位于屏幕最中间。本文先列举12个&#xff0c;供大家欣赏。 1.地球 2.世界地图 3.中国 4.行政区划 5.社区 6.园区 7.城市 8.场馆 9.建筑 10.工厂 11.设备 12.流程/组态

Excel 宏录制与VBA编程 —— 14、使用VBA处理Excel事件

简介 若希望特定事件处理程序在触发特定事件时运行&#xff0c;可以为 Application 对象编写事件处理程序。 Application 对象的事件处理程序是全局的&#xff0c;这意味着只要 Microsoft Excel 处于打开状态&#xff0c;事件处理程序将在发生相应的事件时运行&#xff0c;而不…

Spring Cloud Gateway3.x自定义Spring Cloud Loadbalancer负载均衡策略以及实现动态负载均衡策略的方案

目录 前言 1.原理分析 1.1 ReactiveLoadBalancerClientFilter源码分析 1.2 LoadBalancerClientFactory源码分析 2.代码实现 2.1 扩展原生RoundRobinLoadBalancer轮询策略 2.1.1 自定义实现RoundRobinLoadBalancer 2.1.2 配置自定义的RoundRobinLoadBalan…