C++类和对象-继承->基本语法、继承方式、继承中的对象模型、继承中构造和析构顺序、继承同名成员处理方式、继承同名静态成员处理方式、多继承语法、菱形继承

#include<iostream>
using namespace std;

//普通实现页面
//Java页面
//class Java
//{
//public:
//    void header()
//    {
//        cout << "首页、公开课、登录、注册...(公共头部)" << endl;
//    }
//    void footer()
//    {
//        cout << "帮助中心、交流合作、站内地图...(公共底部)" << endl;
//    }
//    void left()
//    {
//        cout << "Java,Python,C++...(公共分类列表)" << endl;
//    }
//    void content()
//    {
//        cout << "JAVA学科视频" << endl;
//    }
//};
Python页面
//class Python
//{
//public:
//    void header()
//    {
//        cout << "首页、公开课、登录、注册...(公共头部)" << endl;
//    }
//    void footer()
//    {
//        cout << "帮助中心、交流合作、站内地图...(公共底部)" << endl;
//    }
//    void left()
//    {
//        cout << "Java,Python,C++...(公共分类列表)" << endl;
//    }
//    void content()
//    {
//        cout << "Python学科视频" << endl;
//    }
//};
C++页面
//class CPP
//{
//public:
//    void header()
//    {
//        cout << "首页、公开课、登录、注册...(公共头部)" << endl;
//    }
//    void footer()
//    {
//        cout << "帮助中心、交流合作、站内地图...(公共底部)" << endl;
//    }
//    void left()
//    {
//        cout << "Java,Python,C++...(公共分类列表)" << endl;
//    }
//    void content()
//    {
//        cout << "C++学科视频" << endl;
//    }
//};
//
//void test01()
//{
//    //Java页面
//    cout << "Java下载视频页面如下: " << endl;
//    Java ja;
//    ja.header();
//    ja.footer();
//    ja.left();
//    ja.content();
//    cout << "--------------------" << endl;
//
//    //Python页面
//    cout << "Python下载视频页面如下: " << endl;
//    Python py;
//    py.header();
//    py.footer();
//    py.left();
//    py.content();
//    cout << "--------------------" << endl;
//
//    //C++页面
//    cout << "C++下载视频页面如下: " << endl;
//    CPP cp;
//    cp.header();
//    cp.footer();
//    cp.left();
//    cp.content();
//
//}
//
//int main()
//{
//    test01();
//
//    system("pause");
//    return 0;
//}

//继承实现页面
//公共页面
class BasePage
{
public:
    void header()
    {
        cout << "首页、公开课、登录、注册...(公共头部)" << endl;
    }

    void footer()
    {
        cout << "帮助中心、交流合作、站内地图...(公共底部)" << endl;
    }
    void left()
    {
        cout << "Java,Python,C++...(公共分类列表)" << endl;
    }

};
//继承的好处:减少重复代码
//语法:  class 子类:继承方式 父类
//子类  也称为  派生类
//父类  也称为   基类

//Java页面
class Java : public BasePage
{
public:
    void content()
    {
        cout << "JAVA学科视频" << endl;
    }
};
//Python页面
class Python : public BasePage
{
public:
    void content()
    {
        cout << "Python学科视频" << endl;
    }
};
//C++页面
class CPP : public BasePage
{
public:
    void content()
    {
        cout << "C++学科视频" << endl;
    }
};

void test01()
{
    //Java页面
    cout << "Java下载视频页面如下: " << endl;
    Java ja;
    ja.header();
    ja.footer();
    ja.left();
    ja.content();
    cout << "--------------------" << endl;

    //Python页面
    cout << "Python下载视频页面如下: " << endl;
    Python py;
    py.header();
    py.footer();
    py.left();
    py.content();
    cout << "--------------------" << endl;

    //C++页面
    cout << "C++下载视频页面如下: " << endl;
    CPP cp;
    cp.header();
    cp.footer();
    cp.left();
    cp.content();


}

int main() {

    test01();

    system("pause");

    return 0;
}

#include<iostream>
using namespace std;

//继承方式
//公共继承
class Base1
{
public:
    int m_A;
protected:
    int m_B;
private:
    int m_C;
};

class Son1 :public Base1
{
public:
    void func()
    {
        //可访问 public权限
        m_A;//父类中的公共权限成员 到子类中依然是公共权限
        //可访问 protected权限
        m_B; //父类中的保护权限成员 到子类中依然是保护权限
        //不可访问
        //m_C; //父类中的私有权限成员  子类访问不到
    }
};

void myClass()
{
    Son1 s1;
    s1.m_A = 100; //其他类只能访问到公共权限
    //s1.m_B = 100;//到Son1中 m_B是保护权限 类外访问不到
}

//保护继承
class Base2
{
public:
    int m_A;
protected:
    int m_B;
private:
    int m_C;
};
class Son2:protected Base2
{
public:
    void func()
    {
        //可访问 protected权限
        m_A;   //父类中公共成员,到子类中变为保护权限
        //可访问 protected权限
        m_B;   //父类中保护成员,到子类中变为保护权限
        //不可访问
        //m_C; //父类中私有成员  子类访问不到
    }
};
void myClass2()
{
    Son2 s;
    //不可访问
    //s.m_A = 100; //在Son2中 m_A变为保护权限,因此类外访问不到
    //s.m_B = 100; //在Son2中 m_B变保护权限,不可以访问
}

//私有继承
class Base3
{
public:
    int m_A;
protected:
    int m_B;
private:
    int m_C;
};
class Son3:private Base3
{
public:
    void func()
    {
        //可访问 private权限
        m_A; //父类中公共成员,到子类中变为私有成员
        //可访问 private权限
        m_B; //父类中保护成员,到子类中变为私有成员
        //不可访问
        //m_C; //父类中私有成员  子类访问不到
    }
};

class GrandSon3 :public Son3
{
public:
    void func()
    {
        //Son3是私有继承,所以继承Son3的属性在GrandSon3中都无法访问到
        //m_A = 1000;//到了Son3中 m_A变为私有,即使是儿子,也是访问不到
        //m_B = 1000;//到了Son3中 m_B变为私有,即使是儿子,也是访问不到

    }
};

void myClass3()
{
    Son3 s;
    //不可访问
    //s.m_A = 1000; //在Son3中 变为私有成员  类外访问不到
    //s.m_B = 1000; //在Son3中 变为私有成员  类外访问不到
}

#include<iostream>
using namespace std;

//继承中的对象模型
class Base
{
public:
    int m_A;
protected:
    int m_B;
private:
    int m_C; //私有成员只是被隐藏了,但是还是会继承下去
};

//公共继承
class Son :public Base
{
public:
    int m_D;
};

//利用开发人员命令提示工具查看对象模型
//跳转盘符 F:
//跳转文件路径 cd 具体路径下
//查看命名
//cl /d1 reportSingleClassLayout类名 文件名

void test01()
{
    //16
    //父类中所有非静态成员属性都会被子类继承下去
    //父类中私有成员属性 是被编译器给隐藏了,因此是访问不到,但是确实被继承下去了
    cout << "sizeof Son = " << sizeof(Son) << endl;
}

int main() {

    test01();

    system("pause");

    return 0;
}

结论:父类中私有成员也是被子类继承下去了,只是由编译器给隐藏后访问不到

#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;
    }

};


void test01()
{
    //继承中 先调用父类构造函数,再调用子类构造函数,析构顺序与构造相反
    Son s;
}

int main() {

    test01();

    system("pause");

    return 0;
}

总结:继承中 先调用父类构造函数,再调用子类构造函数,析构顺序与构造相反

#include<iostream>
using namespace std;

//继承中同名成员处理
class Base
{
public:
    Base()
    {
        m_A = 100;
    }

    void func()
    {
        cout << "Base - func()调用" << endl;
    }

    void func(int a)
    {
        cout << "Base - func(int a)调用" << endl;
    }

public:
    int m_A;
};


class Son : public Base
{
public:
    Son()
    {
        m_A = 200;
    }

    //当子类与父类拥有同名的成员函数,子类会隐藏父类中所有版本的同名成员函数
    //如果想访问父类中被隐藏的同名成员函数,需要加父类的作用域
    void func()
    {
        cout << "Son - func()调用" << endl;
    }
public:
    int m_A;
};

void test01()
{
    Son s;

    //同名成员属性
    cout << "Son下的m_A = " << s.m_A << endl;
    //如果通过子类对象 访问到父类中同名成员,需要加作用域
    cout << "Base下的m_A = " << s.Base::m_A << endl;

    //同名成员函数
    s.func();//直接调用 调用的是子类中的同名成员
    s.Base::func();
    s.Base::func(10);

}
int main() {

    test01();

    system("pause");
    return EXIT_SUCCESS;
}

总结:

1. 子类对象可以直接访问到子类中同名成员
2. 子类对象加作用域可以访问到父类同名成员
3. 当子类与父类拥有同名的成员函数,子类会隐藏父类中同名成员函数,加作用域可以访问到父类中同名函数

#include<iostream>
using namespace std;

//继承中的同名静态成员处理方式
class Base
{
public:
    static void func()
    {
        cout << "Base - static void func()" << endl;
    }
    static void func(int a)
    {
        cout << "Base - static void func(int a)" << endl;
    }

    static int m_A;
};

int Base::m_A = 100;

class Son : public Base {
public:
    static void func()
    {
        cout << "Son - static void func()" << endl;
    }
    static int m_A;
};

int Son::m_A = 200;

//同名静态成员属性
void test01()
{
    //1.通过对象访问
    cout << "通过对象访问: " << endl;
    Son s;
    cout << "Son  下 m_A = " << s.m_A << endl;
    cout << "Base 下 m_A = " << s.Base::m_A << endl;

    //2.通过类名访问
    cout << "通过类名访问: " << endl;
    cout << "Son  下 m_A = " << Son::m_A << endl;
    //第一个::代表通过类名方式访问 第二个::代表访问父类作用域下
    cout << "Base 下 m_A = " << Son::Base::m_A << endl;
}

//同名静态成员函数
void test02()
{
    //1.通过对象访问
    cout << "通过对象访问: " << endl;
    Son s;
    s.func();
    s.Base::func();
    //2.通过类名访问
    cout << "通过类名访问: " << endl;
    Son::func();
    Son::Base::func();
    //出现同名,子类会隐藏掉父类中所有同名成员函数,需要加作作用域访问
    Son::Base::func(100);
}
int main() {

    //test01();
    test02();

    system("pause");

    return 0;
}

 总结:同名静态成员处理方式和非静态处理方式一样,只不过有两种访问的方式(通过对象 和 通过类名)

#include<iostream>
using namespace std;

//多继承语法

class Base1
{
public:
    Base1()
    {
        m_A = 100;
    }
public:
    int m_A;
};

class Base2 {
public:
    Base2()
    {
        m_A = 200;  //开始是m_B 不会出问题,但是改为m_A就会出现不明确
    }
public:
    int m_A;
};

//语法:class 子类:继承方式 父类1 ,继承方式 父类2
class Son : public Base2, public Base1
{
public:
    Son()
    {
        m_C = 300;
        m_D = 400;
    }
public:
    int m_C;
    int m_D;
};


//多继承容易产生成员同名的情况
//通过使用类名作用域可以区分调用哪一个基类的成员
void test01()
{
    Son s;
    cout << "sizeof Son = " << sizeof(s) << endl;
    //当父类中出现同名成员,需要加作用域区分
    cout << s.Base1::m_A << endl;
    cout << s.Base2::m_A << endl;
}

int main()
{

    test01();

    system("pause");

    return 0;
}

总结: 多继承中如果父类中出现了同名情况,子类使用时候要加作用域

#include<iostream>
using namespace std;

//动物类
class Animal
{
public:
    int m_Age;
};
//利用虚继承 解决菱形继承的问题
//继承前加virtual关键字后,变为虚继承
//此时公共的父类Animal称为虚基类
//羊类
class Sheep : virtual public Animal {};
//驼类
class Tuo   : virtual public Animal {};
//羊驼类
class SheepTuo : public Sheep, public Tuo {};

void test01()
{
    SheepTuo st;
    st.Sheep::m_Age = 100;
    st.Tuo::m_Age = 300;
    //当菱形继承,两个父类拥有相同数据,需要加以作用域区分
    cout << "st.Sheep::m_Age = " << st.Sheep::m_Age << endl;
    cout << "st.Tuo::m_Age = " <<  st.Tuo::m_Age << endl;
    cout << "st.m_Age = " << st.m_Age << endl;
    //这份数据我们知道  只有一份就可以,菱形继承导致数据有两份,资源浪费
    
}


int main() {

    test01();

    system("pause");

    return 0;
}

总结:

* 菱形继承带来的主要问题是子类继承两份相同的数据,导致资源浪费以及毫无意义
* 利用虚继承可以解决菱形继承问题

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

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

相关文章

Phobos捆绑某数控软件AdobeIPCBroker组件定向勒索

前言 Phobos勒索病毒最早于2019年被首次发现并开始流行起来&#xff0c;该勒索病毒的勒索提示信息特征与CrySiS(Dharma)勒索病毒非常相似&#xff0c;但是两款勒索病毒的代码特征却是完全不一样&#xff0c;近日笔者在逛某开源恶意软件沙箱的时候发现了一款Phobos勒索病毒捆绑…

sql语句学习(一)--查询

【有道云笔记】基本sql语句2—查询基础 数据库表结构 DROP TABLE IF EXISTS class; CREATE TABLE class (id int(11) NOT NULL AUTO_INCREMENT,class_num varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT 班级号,class_name varchar(255) CHARACTE…

第24讲投票管理实现

投票管理实现 后端&#xff1a; package com.java1234.controller;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.java1234.entity.*; import com.java1234.service.…

QEMU使用步骤

1、安装虚拟机环境&#xff1a;ubuntu-16.04.7-desktop-amd64.iso,下载地址&#xff1a;Index of /ubuntu-releases/16.04.7/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror 2、安装gcc-linaro-7.3.1-2018.05-x86_64_arm-linux-gnueabihf.tar.xz到/opt目录&#xf…

SECS/GEM的HSMS通讯?金南瓜方案

High Speed SECS Message Service (HSMS) 是一种基于 TCP/IP 的协议&#xff0c;它使得 SECS 消息通信更加快速。这通常用作设备间通信的接口。 HSMS 状态逻辑变化&#xff08;序列&#xff09;&#xff1a; 1.Not Connected&#xff1a;准备初始化 TCP/IP 连接&#xff0c;但尚…

第十九篇【传奇开心果系列】Python的OpenCV库技术点案例示例:文字识别与OCR

传奇开心果短博文系列 系列短博文目录Python的OpenCV库技术点案例示例系列 短博文目录前言一、OpenCV 文字识别介绍二、图像预处理示例代码三、文字区域检测示例代码四、文字识别示例代码五、文字后处理示例代码六、OpenCV结合Tesseract OCR库实现文字识别示例代码七、OpenCV结…

【Cocos入门】物理系统(物理碰撞)

物理碰撞 物理引擎默认是关闭状态以节省资源开销。开启方法和之前的普通碰撞类似&#xff1a;cc.director.getPhysicsManager().enabled true但有一个区别&#xff0c;物理引擎的开启必须放在onLoad函数内运行&#xff0c;否则不生效。 物理碰撞组件也同样具有碰撞回调函数。…

9 个管理 Windows 硬盘的最佳免费磁盘分区软件 [2024 排名]

管理分区可能是一项具有挑战性的任务。当您想到删除、缩小、移动、磁盘分区或合并分区等方面时&#xff0c;您会认为它们是很难做到的事情。然而&#xff0c;虽然 Windows 自己的磁盘管理可以处理大部分问题&#xff0c;但它无法处理管理分区的所有方面。 这时候优质的磁盘管理…

半导体通讯SECS-I是什么?

SECS-I&#xff08;Semi Equipment Communications Standard 1 Message Transfer&#xff09;是一个定义如何发送和接收通信内容&#xff08;Content&#xff09;的协议。此标准定义了通过RS-232C传输介质进行通信内容的发送和接收规约。 其主要特点如下&#xff1a; 1.使用RS2…

android 控制台输出 缺失

问题 android 控制台输出内容缺失 详细问题 笔者进行android开发&#xff0c;期望控制台打印Log日志或是输出内容 Log.i("tag","content");或 System.out.println("content")但是实际上&#xff0c;上述内容并没有按照笔者期望打印 解决方…

84 CTF夺旗-PHP弱类型异或取反序列化RCE

目录 案例1&#xff1a;PHP-相关总结知识点-后期复现案例2&#xff1a;PHP-弱类型对比绕过测试-常考点案例3&#xff1a;PHP-正则preg_match绕过-常考点案例4&#xff1a;PHP-命令执行RCE变异绕过-常考点案例5&#xff1a;PHP-反序列化考题分析构造复现-常考点涉及资源&#xf…

2024.02.14作业

1. 请编程实现二维数组的杨辉三角 #include <stdio.h> #include <stdlib.h> #include <string.h>int main() {int n;scanf("%d", &n);int a[n][n];memset(a, 0, sizeof(a));a[0][0] 1;for (int i 1; i < n; i){for (int j 0; j < i …

tick数据、盘口数据、成交明细数据详解

近期开始学习订单薄策略(order book strategy)、订单流策略(order flow strategy)&#xff0c;理清数据是第一步。 一、成交明细数据 用各个软件进行看盘&#xff0c;除了分时、k线最常用外&#xff0c;盘口数据/成交明细也会显示出来&#xff0c;下图是螺纹主力shfe.rb2401 …

auto关键字详讲

目录 1.问题思考 2.auto关键字介绍 3. 早期auto的缺陷&#xff1a; 4.什么叫自动存储器&#xff1f; 5. c标准auto关键字 5.1auto的使用细节 5.2 auto什么时候不能推导变量的类型呢&#xff1f; 5.3基于范围的for循环 5.3.1范围for的用法 5.3.2 范围for的使用条件 6.…

C语言学习day14:跳转语句

今天学习的跳转语句主要是三种&#xff1a; break continue goto 上一篇文章已经说过了break和continue break&#xff1a;结束这个循环 continue&#xff1a;结束当前的循环迭代&#xff0c;进行下一次的迭代 看看二者代码的区别 代码&#xff08;break&#xff09;&am…

奔跑吧小恐龙(Java)

前言 Google浏览器内含了一个小彩蛋当没有网络连接时&#xff0c;浏览器会弹出一个小恐龙&#xff0c;当我们点击它时游戏就会开始进行&#xff0c;大家也可以玩一下试试&#xff0c;网址&#xff1a;恐龙快跑 - 霸王龙游戏. (ur1.fun) 今天我们也可以用Java来简单的实现一下这…

Nodejs 第三十七章(连表and子查询)

子查询 子查询&#xff08;Subquery&#xff09;&#xff0c;也被称为嵌套查询&#xff08;Nested Query&#xff09;&#xff0c;是指在一个查询语句中嵌套使用另一个完整的查询语句。子查询可以被视为一个查询的结果集&#xff0c;它可以作为外层查询的一部分&#xff0c;用…

Spring Boot 笔记 015 创建接口_更新文章分类

1.1.1 实体类id增加NotNull注释&#xff0c;并做分组校验 1.1.1.1 定义分组 1.1.1.2 实体类中指定校验项属于哪个分组 如果说某个校验项没有指定分组,默认属于Default分组 分组之间可以继承, A extends B 那么A中拥有B中所有的校验项package com.geji.pojo;import com.faste…

linux安装mysql8且初始化表名忽略大小写

mysql8下载地址 MySQL8.0安装步骤 1、把安装包上传到linux系统&#xff0c;解压、重命名并移动到/usr/local/目录&#xff1a; cd ~ tar -xvf mysql-8.0.32-linux-glibc2.12-x86_64.tar.xz mv mysql-8.0.32-linux-glibc2.12-x86_64/ mysql80/ mv mysql80/ /usr/local/2、在M…

基于HTML5实现动态烟花秀效果(含音效和文字)实战

目录 前言 一、烟花秀效果功能分解 1、功能分解 2、界面分解 二、HTML功能实现 1、html界面设计 2、背景音乐和燃放触发 3、燃放控制 4、对联展示 5、脚本引用即文本展示 三、脚本调用及实现 1、烟花燃放 2、燃放响应 3、烟花canvas创建 4、燃放声音控制 5、实际…