• 植物大战 继承——C++


    “物是人非事事休, 欲语泪先流”

    猛戳订阅🍁🍁 👉 [C++详解专栏] 👈 🍁🍁

    一、继承的概念以及定义

    继承机制是面向对象程序设计使得代码可以复用的重要手段,它允许程序员在保持原有类的特性的基础上进行扩展,增加功能,这样产生新的类,为派生类

    继承呈现了面向对象程序设计的层次结构。提现到了由简单到复杂的认知过程。

    以前接触的复用都是函数复用,继承是类设计层次的复用

    //父类
    class A
    {
    public:
    	void Print()
    	{
    		cout << "_a" << endl;
    	}
    protected: 
    	int _a;
    };
    //子类
    class B : public A
    {
    protected:
    	int _b;
    };
    
    
    
    

    注意:实例化出来的对象里面不存方法,只存成员变量。

    1.继承方法

    重点:
    1.在实际中父类成员基本都是保护和共有

    2.protected和private成员对于基类都是一样的。
    3.protected成员对于子类来说是可以使用的,而private成员
    不可以用
    保护继承是在类内可以访问,在类外不能访问。

    私有继承派生类中都是不可见。但不可见得意思是:私有的成员变量在子类里面,但是语法限制你不能访问

    访问的权限是:保护继承,公有继承,取小的那个。

    二、基类和派生类对象赋值转换

    派生类对象可以赋值给基类的对象,指针,和基类的引用。这里有个形象的说法叫做切割或者切片。(也叫作向上转换)

    普通对象之间赋值会产生临时对象。但这个过程是天然的,没有类型转换。(这个在C++中很重要)这个叫做赋值兼容转换

    注意
    引用的是子类的一部分别名。

    指针是指向父类的一部分

    三、继承中的作用域

    基类 和 派生类 都会形成独立的作用域。

    2.隐藏

    隐藏:在不同的中会有相同的名称的变量。这时子类会对父类进行隐藏,也叫作重定义。

    隐藏的话想访问父类的变量,则需要加类域限定符::
    最好不要用重名的变量。

    成员函数也会重名,成员函数和成员变量一样。都会构成隐藏
    只要成员函数名相同就会构成隐藏
    但有一点需要注意:函数重载要求在同一作用域。在同一作用域才探讨重载。重载需要函数名相同,参数不同

    但隐藏是在不同的作用域!

    四、派生类的默认成员函数

    默认的意思,就是我们不写,编译器自动生成的构造函数。

    子类构造函数原则
    1.先调用父类的构造函数,来初始化继承自父类的成员。
    2.然后再初始化自己的成员。

    析构、拷贝构造,赋值重载也类似。也是以上的原则。

    父类的成员一定要调父类的构造函数初始化。初始化列表就是调用默认构造函数的地方。

    1.拷贝构造

    先在初始化列表调用父类的默认构造函数,再初始化子类的成员。

    2.赋值重载拷贝

    注意子类的operator=和父类的构成了隐藏,要记得加类域限定符::

    3.析构函数

    析构函数比较特殊。这是C++特殊的地方
    析构函数不用调用父类的析构函数。这里比较特殊,构成了隐藏。

    父类的析构函数和子类的析构函数构成了隐藏关系

    因为1.由于多态的需要,析构函数统一处理成了destructor().
    2.为了保证析构顺序,会先调用子类,再自动调用父类的析构函数,不需要我们显式的调用。

    这跟我们的存储的顺序有关,先定义的后析构。

    4.如何设计一个不能被继承的类?

    不能创建子类的对象,因为创建子类的对象,就要调用父类的构造函数。但是父类的构造函数是一个私有的。所以这个类不能被继承。

    //父类
    class A
    {
    private:
    	A()
    	{
    		
    	}
    };
    //子类
    class B : public A
    {
    
    };
    int main()
    {
    	B b;//错误。不能创建对象
    	return 0;
    }
    

    五、继承与友元

    友元不能继承,友元的关系不能继承下来。

    你是父亲的朋友,但不一定是儿子的朋友。

    六、继承的静态成员变量

    父类的静态变量子类都会继承下来。

    C++静态成员变量需要在类外定义和初始化。

    //父类构造函数
    class Person
    {
    public:
    	Person()
    	{
    		++_count;
    	}
    protected:
    	string _name;
    	//静态成员变量
    public:
    	static int _count;
    };
    //C++静态成员变量一定要在类外进行定义和初始化。
    int Person::_count = 0;
    
    class Student :public Person
    {
    protected:
    	int _stuNum;
    };
    
    class Graduate : public Student
    {
    protected:
    	string _course;
    };
    int main()
    {
    	Student s1;
    	Student s2;
    	Student s3;
    
    	Graduate s4;
    	cout << "人数:" << Person::_count << endl;
    	Student::_count = 0;
    	cout << "人数:" << Person::_count << endl;
    
    	return 0;
    }
    

    七、多继承(了解)

    单继承:一个子类只有一个直接父类叫做单继承。

    多继承:一个子类有两个或两个以上的直接父类就叫做多继承。
    在这里插入图片描述

    1.菱形继承

    菱形继承是多继承的一种特殊情况。它会产生数据冗余,和二义性,子类会同时继承两个父类的两份数据,造成了二义性。

    因为这个缺点,所以java是没有多继承的

    2.虚继承

    虚继承可以说是C++的缺陷了。

    怎么解决菱形继承这个问题呢?
    这个就叫做虚继承,在腰部的位置加上关键字virtual

    这时候vs的监视窗口看到的东西已经不准了。

    3.对象模型

    普通多继承的对象模型。
    在这里插入图片描述

    虚继承
    在这里插入图片描述多了两个指针区域,每个指针四个字节,用来存储距离A位置的偏移量,用来计算A的位置。

    重点理解就是,B和C有个A但是A没有存在B和C的位置,所以需要通过偏移量找到A。

    A就叫做虚基类。
    存放指针的区域的指针,叫做虚基表指针。

    为什么要存储A的偏移量,因为d赋值给b,在赋值的时候,需要找A的位置,需要切片,切片需要通过偏移量计算A的位置。

    八、面向对象三大特性

    面向对象不止三大特性:还有java的反射、抽象

    什么是封装、继承、多态?这个问题是没有标准答案的。

    1.封装

    主要是和C语言对比,C语言数据和方法是分开的,而C++是放在一起的。
    例如:1.C语言的Stack和C++的Stack对比。
    狭义的:
    封装更好。来讲:封装指的是 访问限定符+类的封装。

    广义的封装:例如封装了容器底层结构。封装其实也是一种隐藏

    2.迭代器的设计:
    如果没有迭代器,容器的访问只能暴露底层结构。暴露的话,使用复杂,使用成本很高对使用者的要求也极高。你得懂二叉树,链表。假如有迭代器的话,使用非常的方便!

    封装的好处:在不暴露底层结构情况下,提供统一的访问容器的方式。

    3.优先级队列的设计。–适配器模式。

    假如不用适配器,就要自己写一个stack,queue,priority_queue。

    2.继承

    继承的本质就是:类设计角度的复用。
    继承就是在更高的维度来设计类。

    继承是类与类之间的关系。

    有些数据和方法是每个角色都有的。有些是独有的。都有的就是重复的。

    继承就是把那些每个角色都有的数据和方法提取出来。然后做成一个类。

    其他独立的数据和方法就可以单独作为一个类来继承。

  • 相关阅读:
    训练DeeplabV3+来分割车道线
    Qwt开发笔记(二):Qwt基础框架介绍、折线图介绍、折线图Demo以及代码详解
    WebGIS-分辨率与比例尺
    TX Text Control.NET 32.0 For WPF
    无规律快速批量重命名文件(夹)-固定命名
    Java with RocketMQ
    知识库系统推荐,强大的全文检索与文档分类管理功能
    Redis阅读——内存分配
    腾讯云 BI 数据分析与可视化的快速入门指南
    【电商项目实战】用户登录(详细篇)
  • 原文地址:https://blog.csdn.net/qq2466200050/article/details/127062817