C++(6) 继承

文章目录

      • 继承
        • 1. 继承
          • 1.1 什么是继承
          • 1.2 C++ 继承方式
            • 1.2.1 基本案例
            • 1.2.2 继承权限组合
            • 1.2.3 继承中构造函数的说法
            • 1.2.4 继承中析构函数的执行顺序
            • 1.2.5 继承中变量名称冲突问题
            • 1.2.6 继承中函数【重写】

继承

1. 继承
1.1 什么是继承

面向对象程序设计中最重要的一个概念是继承。继承允许我们依据另一个类来定义一个类,这使得创建和维护一个应用程序变得容易。达到重写代码功能和提高执行效率的效果。

当创建一个类时,不需要重新编写新的数据成员和成员函数, 只需要指定新键的类继承了一个已有的类的成员即可。这个已有的类称为基类,新建的类称为派生类

1.2 C++ 继承方式
1.2.1 基本案例

格式

class 子类 : 权限修饰符
{
}
#include <iostream>

using namespace std;

class Base
{
public:
    int mA = 1;
protected:
    int mB = 2;
private:
    int mC = 3;
};

/*
Base 类是 Son 的一个 public 修饰父类
Son 类是 Base 类的一个子类,或者可以认为 Son 类是 Base 类 派生类
*/
class Son : public Base
{
public:
    int nA = 1;
protected:
    int nB = 2;
private:
    int nC = 3;
};

int main(int argc, char const *argv[])
{
    Son * s = new Son;

    cout << "mA : " << s->mA << endl;
    // 当情况下,mB 是 Base 类中的 protected 修饰 成员变量,同时使用 public 方式继承
    // 子类对象无法在类外调用 mB
    // cout << "mB : " << s->mB << endl;
    // 当情况下,mB 是 Base 类中的 protected 修饰 成员变量,同时使用 public 方式继承
    // 子类对象无法s使用mC
    // cout << "mC : " << s->mC << endl;

    cout << "nA : " << s->nA << endl;

    // cout << "nB : " << s->nB << endl;

    // cout << "nC : " << s->nC << endl;

    return 0;
}
1.2.2 继承权限组合
继承对应的权限修饰\原修饰符publicprotectedprivate
publicpublicprotected无法继承
protectedprotectedprotected无法继承
privateprivateprivate无法继承
#include <iostream>

using namespace std;

/*
public:
    类内、子类类外都可以使用
protected:
    类内、子类可以使用,类外无法使用
private:
    类内可以使用,子类、类外无法使用
*/
class Base
{
public:
    int mA = 1;
    void test1() { cout << "test1 funtion" << endl; }
protected:
    int mB = 1;
    void test2() { cout << "test2 funtion" << endl; }
private:
    int mC = 1;
    void test3() { cout << "test3 funtion" << endl; }
};

/*
public 继承方式,父类的成员权限修饰符变化
    public --> public
    protected --> protected
    private 无法继承
*/
class Son1: public Base
{
public:
    void test()
    {
        cout << mA << endl;
        cout << mB << endl;
        // cout << mC << endl;

        test1();
        test2();
        // test3();
    }
};

/*
protected 继承方式,父类的成员权限修饰符变化
    public --> protected
    protected --> protected
    private 无法继承
*/
class Son2: protected Base
{
public:
    void test()
    {
        cout << mA << endl;
        cout << mB << endl;
        // cout << mC << endl;

        test1();
        test2();
        // test3();
    }
};

/*
private 继承方式,父类的成员权限修饰符变化
    public --> private
    protected --> private
    private 无法继承
*/
class Son3: private Base
{
    void test()
    {
        cout << mA << endl;
        cout << mB << endl;
        // cout << mC << endl;
    }
};


int main(int argc, char const *argv[])
{
    Son1 *s1 = new Son1;
    cout << s1->mA << endl;

    Son2 *s2 = new Son2;
    // cout << s2->mA << endl;

    Son3 *s3 = new Son3;
    // cout << s3->mA << endl;
    
    return 0;
}
1.2.3 继承中构造函数的说法
#include <iostream> 

using namespace std;

class Base
{
public:
    Base()
    {
        cout << "Base 类中的构造函数" << endl;
    }

    ~Base()
    {
        cout << "Base 类析构函数" << endl;
    }
};

class Son : public Base
{
public:
    Son()
    {
        cout << "Son 类构造函数" << endl;
    }
    ~Son()
    {
        cout << "Son 类析构函数" << endl;
    }
};

class GrandSon : public Son
{
public:
    GrandSon()
    {
        cout << "GrandSon 类析构函数" << endl;
    }
    ~GrandSon()
    {
        cout << "GrandSon 类析构函数" << endl;
    }
};

int main(int argc, char const *argv[])
{
    // 显式调用的时子类的五承诺书构造函数
    Son *s1 = new Son();
    /*
    Base 类构造函数
    Son 类构造函数
    */
    cout << "----------------------------------" << endl;
    delete s1;
    /*
    Son 类析构函数
    Base 类析构函数
    */
    cout << "----------------------------------" << endl;

    GrandSon *s2 = new GrandSon();
    /*
    Base 类构造函数
    Son 类构造函数
    GrandSon 类构造函数
    */
    cout << "----------------------------------" << endl;

    delete s2;
    /*
    GranSon 类析构函数
    Son 类析构函数
    Base 类析构函数
    */

    return 0;
}
1.2.4 继承中析构函数的执行顺序

在这里插入图片描述

1.2.5 继承中变量名称冲突问题
class Base
{
public:
    int num;
};

class Son : public Base
{
public:
    int num;
    
    void test()
    {
        // int Son::num;
        /*
        如果直接使用,编译器会考虑按照就近原则方式进行数据分配
        首选是 Son 类中的 num 数据
        */
        cout << num << endl;
        // int Base::num;
        /*
        如果需要使用 Base 中的 num,需要利用 :: 作用域运算符
        限制当前变量的作用范围
        */
        cout << Base::num << endl;
    }
};
1.2.6 继承中函数【重写】
#include <iostream>

using namespace std;

class Father
{
public:
    void name() { cout << "小鱼丸" << endl; }
    void hobby() { cout << "唱歌" << endl; }
};

/*
函数的重写 Ovreride
    1. 存在必要的继承关系
    2. 要求子类重写父类的函数,函数声明必须一致
    3. 可以按照子类要求完成哈桑农户内容实现

重写的存在可以降低开发中函数命名压力
*/
class Son : public Father
{
public:
    void name() { cout << "Glade" << endl; }
    void hobby() { cout << "吃" << endl; }
};

int main(int argc, char const *argv[])
{
    Son * s = new Son;  

    /*
    子类可以通过 public 继承得到父类中 public 修饰函数,
    类内调用但是父类的函数有可能无法满足子类的特征需求

    【重写父类函数】 Override
    */
    s->name();
    s->hobby();

    return 0;
}
{
public:
    void name() { cout << "Glade" << endl; }
    void hobby() { cout << "吃" << endl; }
};

int main(int argc, char const *argv[])
{
    Son * s = new Son;  

    /*
    子类可以通过 public 继承得到父类中 public 修饰函数,
    类内调用但是父类的函数有可能无法满足子类的特征需求

    【重写父类函数】 Override
    */
    s->name();
    s->hobby();

    return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C语言——指针进阶(四)

目录 一.前言 二.指针和数组笔试题解析 2.1 二维数组 2.2 指针笔试题 三.全部代码 四.结语 一.前言 本文我们将迎来指针的结尾&#xff0c;包含了二维数组与指针的试题解析。码字不易&#xff0c;希望大家多多支持我呀&#xff01;&#xff08;三连&#xff0b;关注&…

网络基础二 session、cookie、token

HTTP协议以明文方式发送内容&#xff0c;不提供任何方式的数据加密&#xff0c;如果攻击者截取了Web浏览器和网站服务器之间的传输报文&#xff0c;就可以直接读懂其中的信息&#xff0c;因此&#xff0c;HTTP协议不适合传输一些敏感信息&#xff0c;比如&#xff1a;信用卡号、…

正则表达式 文本三剑客

一 正则表达式&#xff1a; 由一类特殊字符及文本字符所编写的模式&#xff0c;其中有些字符&#xff08;元字符&#xff09;不表示字符字面意义&#xff0c;而表示控制或通配的功能&#xff0c;类似于增强版的通配符功能&#xff0c;但与通配符不同&#xff0c;通配符功能是用…

Log4j2的Appenders配置详解

官方配置文档 https://logging.apache.org/log4j/2.x/manual/appenders.html#RollingFileAppender <Appenders> 常使用的类如下&#xff1a; org.apache.log4j.ConsoleAppender&#xff08;控制台&#xff09; org.apache.log4j.FileAppender&#xff08;文件&#xff…

【Go-zero】手把手带你在goland中创建api文件并设置高亮

【Go-zero】手把手带你在goland中创建api文件并设置高亮 大家好 我是寸铁&#x1f44a; 总结了一篇手把手带你在goland中创建api文件并设置高亮解决方案的文章✨ 喜欢的小伙伴可以点点关注 &#x1f49d; 问题复盘 在使用go-zero 框架时&#xff0c;常常需要用到goctl 一键生成…

Netty源码二:服务端创建NioEventLoopGroup

示例 还是拿之前启动源码的示例&#xff0c;来分析NioEventLoopGroup源码 NioEventLoopGroup构造函数 这里能看到会调到父类的MultiThread EventLoopGroup的构造方法 MultiThreadEventLoopGroup 这里我们能看到&#xff0c;如果传入的线程数目为0&#xff0c;那么就会设置2倍…

Vue2 props组件通信-父子组件传值

一、父组件向子组件传值 1、流程图 2、父组件代码 <template><div class"app"><UserInfo:usernameusername:ageage:isSingleisSingle:carcar:hobbyhobby></UserInfo></div> </template><script> import UserInfo from .…

汽车网络安全管理体系框架与评价-汽车网络安全管理体系框架

R155《网络安全与网络安全管理系统》法规中明确指出 &#xff0c; 汽车制造商应完成 “汽车网络安全管理体系认证” &#xff08;简称&#xff1a; CSMS认证&#xff09;以及 “车辆型式审批&#xff02; 且CSMS认证&#xff0c;是车辆型式审批的前提条件。 虽然我国相关政策尚…

【网络基础】IP

IP协议报头 4位版本号(version): 指定IP协议的版本, 对于IPv4来说, 就是4.4位头部长度(header length): IP头部的长度是多少个32bit, 也就是 length * 4 的字节数. 4bit表示最大的数字是15, 因此IP头部最大长度是60字节. 8位服务类型(Type Of Service): 3位优先权字段(已经弃用…

C++笔记之作用域解析符::和命名空间、作用域的关系

C++笔记之作用域解析符::和命名空间、作用域的关系 —— 杭州 2024-01-26 code review 文章目录 C++笔记之作用域解析符::和命名空间、作用域的关系1.`命名空间`和`作用域`两个术语的联系和区别命名空间(Namespace)作用域(Scope)联系与区别2.`作用域解析符::`和`命名空间`…

Codeforces Round 785 C. Palindrome Basis

C. Palindrome Basis 题意 定义一个正整数 a a a 是回文的&#xff08;没有前导 0 0 0&#xff09;当且仅当&#xff1a; a a a 的十进制表示形式回文 给定一个正整数 n n n &#xff0c;求出将 n n n 拆分成若干个回文数之和的方案数 思路 这是一个经典模型&#xff0…

Mybatis2:基础操作

Mybatis1 入门 目录 1 基础操作 1.1 准备数据库表 1.2 删除 1.2.1 功能实现 1.2.2 日志输入 1.2.3.1 介绍 1.2.3.2 SQL注入 1.2.3.3 参数占位符 1.3新增 1.3.1 主键返回 1.4更新 1.5 查询 1.5.1 根据ID查询 1.5.2 数据封装 1.5.3参数名说明 1 基础操作 1.1 准备…

107基于51单片机的数字温度计设计[proteus仿真]

基于51单片机的自行车测速系统设计[proteus仿真] 温度检测系统这个题目算是课程设计和毕业设计中常见的题目了&#xff0c;本期是一个基于51单片机的数字温度计设计 需要的源文件和程序的小伙伴可以关注公众号【阿目分享嵌入式】&#xff0c;赞赏任意文章 2&#xffe5;&…

linux -- 内存管理 -- 页面分配器

linux内存管理 为什么要了解linux内存管理 分配并使用内存&#xff0c;是内核程序与驱动程序中非常重要的一环。内存分配函数都依赖于内核中一个非常复杂而重要的组件 - 内存管理。 linux驱动程序不可避免要与内核中的内存管理模块打交道。 linux内存管理可以总体上分为两大…

2024年最新MacBook苹果电脑安装JDK8、JDK11教程,配置环境变量 + 快速切换JDK版本

本帖发布日期&#xff1a;2024年01月26日&#xff0c;全网最新教程整理。 1、概述 本文主要为在MacBook苹果电脑系统下安装JDK及环境变量配置。 教程并非原创&#xff0c;摘抄自互联网&#xff0c;本人作为更新整理亲测。&#xff08;也算给自己记录一贴&#xff09; 本帖分…

数据结构【初阶】--排序(归并排序和基数排序)

目录 一.归并排序的非递归写法 1.思想应用 2.代码基本实现 (1)单趟归并逻辑 (2)多趟&#xff08;循环&#xff09;的控制条件 ① 迭代条件&#xff1a;i2*gap ② 结束条件&#xff1a;i(或i<n-2*gap)<> (3)代码展示 ① 单趟逻辑 ②整体逻辑 3.优化代码…

Springboot响应数据详解

功能接口 Controller下每一个暴露在外的方法都是一个功能接口 功能接口的请求路径是RequestMapping定义的路径&#xff0c;浏览器需要请求该功能则需要发出该路径下的请求。 RestController RestControllerControllerResponseBody(响应数据的注解) ResponseBody 类型&#…

找不到d3dcompiler 43.dll如何解决,5个方法轻松解决d3dcompiler 43.dll问题

计算机系统中d3dcompiler_43.dll文件的丢失可能会引发一系列显著的问题&#xff0c;这一动态链接库文件在Windows操作系统中扮演着至关重要的角色。它主要与Direct3D图形API相关&#xff0c;对于支持和运行使用Direct3D技术开发的各种应用程序和游戏至关重要。 一旦d3dcompiler…

RabbitMQ-如何保证消息不丢失

RabbitMQ常用于 异步发送&#xff0c;mysql&#xff0c;redis&#xff0c;es之间的数据同步 &#xff0c;分布式事务&#xff0c;削峰填谷等..... 在微服务中&#xff0c;rabbitmq是我们经常用到的消息中间件。它能够异步的在各个业务之中进行消息的接受和发送&#xff0c;那么…

sqli.labs靶场(第18~22关)

18、第十八关 经过测试发现User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:122.0) Gecko/20100101 Firefox/122.0加引号报错 这里我们闭合一下试试 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:122.0) Gecko/20100101 Firefox/122.0,127.0.0.1,adm…