C++基础学习(六)继承和派生

1 派生类定义格式:

class 派生类:继承方式 基类名
{
	//派生类新增的数据成员和成员函数
}

2 继承方式

在这里插入图片描述
总结:

继承方式 public protected private
public public还是public protected还是protected private还是private
protected public变成protected protected还是protected private还是private
private public变成private protected变成private private变成private

3 继承中的构造和析构顺序

(1)子类创建对象时,先调用父类的构造,然后调用自身构造
(2)析构顺序与构造顺序相反
(3)子类是不会继承父类的构造函数和析构函数
(4)如果父类中没有合适默认构造,那么子类可以利用初始化列表的方式显示调用父类的其他构造

4 继承中的同名处理

(1)成员属性 直接调用先调用子类,如果想调用父类 需要作用域
(2)成员函数 直接调用先调用子类,父类的所有版本都会被隐藏,除非显示用作用域运算符去调用

5 继承中静态成员的处理

(1)类似非静态成员函数处理
(2)如果想访问父类中的成员,加作用域即可

6 多继承的概念及问题

(1)class A:public B1,public B2,…
(2)引发二义性问题
(3)想解决二义性问题,就需要通过作用域

7 菱形继承问题以及解决

问题:
资源浪费

(1)解决问题利用虚基类
(2)sheepTuo内部结构

  • vbptr 虚基类指针
  • 指向一张 虚基类表
  • 通过表找到偏移量
  • 找到共有的数据
    下面同一个程序来说明:
    这里使用的是:VS 2017的开发人员命令提示符 ,也可以使用其他版本的。
#include <iostream>
using namespace std;

class Animal
{
public:
	int m_Age;
};

class Sheep :public Animal
{};

class Tuo :public Animal
{};

class SheepTuo :public Sheep, public Tuo
{};

void test()
{
	SheepTuo st;
	st.Sheep::m_Age = 10;
	st.Tuo::m_Age = 20;

	cout << st.Sheep::m_Age << endl;
	cout << st.Tuo::m_Age << endl;
}

int main()
{
	test();

	return EXIT_SUCCESS;
}

在这里插入图片描述

#include <iostream>
using namespace std;

class Animal
{
public:
	int m_Age;
};
// 虚基类
class Sheep :virtual public Animal
{
};

class Tuo :virtual public Animal
{

};

class SheepTuo :public Sheep, public Tuo
{

};
// 菱形继承的解决方案 利用虚继承
// 操作共享一份数据
void test()
{
	SheepTuo st;
	st.Sheep::m_Age = 10;
	st.Tuo::m_Age = 20;

	cout << st.Sheep::m_Age << endl;
	cout << st.Tuo::m_Age << endl;
	cout << st.m_Age << endl; // 可以直接访问,原因已经没有二义性的可能了,只有一份m_Age
}

int main()
{
	test();

	return EXIT_SUCCESS;
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_42711815/article/details/88981265