• c++继承与派生知识点



    记录一些遗忘较快的知识,用的不多,时间久了就遗忘;后头番翻书比较费时间,记录一下

    析构函数与构造函数

    1. 析构函数的调用顺序
      先执行派生类的析构函数,对派生类新增加的成员进行清理;然后调用子对象的析构函数,对子对象进行清理;最后调用基类的析构函数,对基类进行清理

    2. 基类的构造函数不能继承,在声明派生类的时候,派生类没有把基类的构造函数继承过来,因此基类成员初始化的工作也要由派生类函数承担;执行派生类构造函数的顺序为: 1)调用基类构造函数,对基类成员初始化;2)调用子对象构造函数,对子对象数据成员初始化;3)在执行派生类构造函数,对派僧类数据成员初始化

    虚基类

    引入虚基类的原因
    当一个派生类有多个直接基类,这些直接基类又有共同的基类,那么直观上这个派生类就包含该间接基类的多份同名成员;在派生类中引用该成员的时候为了避免二义性,就必须在对象名后边添加基类名;这不仅占用了较多的空间,还增加了访问成员的困难;见下边例子的困难

    #include
    #include
    #include
    using namespace std;
    class A1
    {
    public:
    	int a;
    	A1(int aa)
    	{
    		a = aa;
    	}
    };
    class A2
    {
    public:
    	int a;
    	A2(int aa)
    	{
    		a = aa;
    	}
    };
    class A3:public A1,public A2
    {
    public:
    	int b;
    	A3(int v1, int v2, int v3) :A1(v1), A2(v2)
    	{
    		b = v3;
    	}
    };
    
    int main()
    {
    	A3 obj(1, 2, 3);
    	cout << obj.A1::a << endl;
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    虚基类的作用
    虚基类使得在继承共同基类的时候只留下一份成员,就是说共同的基类的对象就留下一份;
    注意虚基类并不是在声明基类的时候声明的,而是在声明派生类的时候指定继承方式的时候声明的;
    虚基类的构造函数,在派生类中构造函数中,以往只需要对派生类的直接基类进行初始化,但是对于虚基类的情况,最后的派生类不仅需要对直接基类进行初始化,而且需要对直接基类的共同基类进行初始化;c++编译系统只执行最后的派生类对虚基类的构造函数的调用,而忽略虚基类的其他派生类对虚函数的构造函数的调用,这就保证了虚基类的数据成员不会被多次初始化;

    使用虚基类以后派生类对象就只保留了共同基类的一份数据,可以直接用品派生类对象进行引用;

    基类与派生类的转换

    公用派生具有基类的全部功能,所有基类能够实现的功能,子类都是实现;其他类型的继承不能实现基类的全部功能;因此只用公用派生才是基类的真正子类型

    1. 赋值兼容
      不同的数据类型之间在一定的条件下可以进行类型的转换,比如说整型数据可以转化为浮点型,这种不同类型数据之间的自动转换和赋值称为赋值加兼容
      那么基类和派生类之间也有赋值兼容的关系;
      1) 派生类对象可以向基类对象赋值
      2) 派生类对象可以替代基类对象向基类对象的引用赋值和初始化
      3) 如果函数的参数是基类对象和基类对象的引用,那么可以将子类的对象传入函数中
      4) 派生类对象的地址可以赋值给指向基类对象的指针,也就是说指向基类对象的指针可以指向派生类对象

    注意
    1) 子类对象可以给父类对象赋值,反之不成立
    2) 指向基类对象的指针可以指向派生类对象,但是只是指向了派生类从基类继承过来的那部分;只能访问派生类中的基类成员,而不能访问派生类中增加的成员;见下例子

    #include
    #include
    #include
    using namespace std;
    class student
    {
    private:
    	string name;
    	int score;
    public:
    	student(string n, int s)
    	{
    		name = n;
    		score = s;
    	}
    	void display()
    	{
    		cout << "name:" << name << endl;
    		cout << "score:" << score << endl;
    		return;
    	}
    };
    
    class graduate:public student
    {
    private:
    	int wage;
    public:
    	graduate(string s, int n, int w) :student(s,n)
    	{
    		wage = w;
    	}
    	void dispaly()
    	{
    		student::display();
    		cout << wage << endl;
    		return;
    	}
    };
    
    int main()
    {
    	student stu("feng haojun", 100);
    	graduate gra("haojun", 100, 100000);
    	student* pt = &stu;
    	pt->display();
    	pt = &gra;
    	cout << endl;
    	pt->display();
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    name:feng haojun
    score:100
    
    name:haojun
    score:100
    
    • 1
    • 2
    • 3
    • 4
    • 5

    可见当基类对象指针指向派生类的时候,调用display函数并不是派生类中的display函数。而是基类对象中的diaplay函数;我的100k工资没有打印出来;
    所以怎么样才能用这种方法把我的wage打印出来给大家看呐,就需要引用虚函数的概念这在下一篇文章介绍

  • 相关阅读:
    Review of English Academic Writing (HITSZ)
    编写 GPT 提示词的公式 + 资源分享
    通关GO语言05 函数和方法:Go 语言中的函数和方法到底有什么不同?
    PTE-精听学习(三)
    排序1:快速排序(三种)、归并排序、计数排序
    Spring JDBC
    spring6-IOC容器
    4. git 添加版本标签
    redis中springboot的redisTemplate简单的增删查
    探索 C++20 的新领域:深入理解 static关键字和核心语言特性测试宏
  • 原文地址:https://blog.csdn.net/qhu1600417010/article/details/126816232