【类的继承与派生的知识点】

类的继承与派生的知识点

类的继承与派生:

  1. 继承与派生:保持已有类的特征构造新类的过程为继承,在已有类的基础上新增特性而产生新类的过程称为派生

  1. 继承目的:实现代码重用;派生目的:实现源程序的改造

  1. 声明:class 派生类:继承方式 基类

  1. 派生类:

吸收基类成员:派生类包含了基类中除了构造析构函数以外的所有成员,构造析构函数不会被继承

改造基类成员:虚函数重写(实际是虚函数表的覆盖)以及同名函数

添加新的成员:加入新的构造析构函数以及其他成员

类成员的访问:

public—>protected—>private注意基类中私有成员不能被访问

基类中的私有成员派生类无法访问
继承方式为public时权限不变,但是私有成员也会被继承?
继承方式为private何protected(体现类的继承特征)时,权限与继承方式一致

类型兼容规则:一个公有派生类的对象在使用上可以被当成基类的对象,反之不行

  1. 派生类的对象可以赋值给基类对象

  2. 派生类的对象可以初始化基类的引用

  3. 指向基类的指针可以指向派生类
    通过基类的对象名与指针只能使用从基类继承的成员

#include<iostream>
#include <string>
using namespace std;
class Base
{
public:
	void showBase()
	{
		cout << "base成员函数的调用" << endl;
	}
};
class Son :public Base
{
public:
	void showSon()
	{
		cout << "Son成员函数的调用" << endl;
	}
};
int main()
{
	Son s1;
	Base b1 = s1;//派生类对象赋值给基类对象
	Base& b2 = s1;//派生类对象初始化基类的引用
	Base* b3 = &s1;//派生类地址初始化基类指针/基类指针指向派生类
	b1.showBase();//通过基类的对象名和指针只能调用基类成员
	b2.showBase();
	b3->showBase();
	return 0;
}


单继承与多继承

  1. 单继承:一个基类一个派生类

  2. 多继承:多基类一派生 class 派生类:继承方式1 基类1, 继承方式2 基类2

  3. 多重派生:一个基类多个派生类

  4. 多层派生:派生类为基类继续派生

派生类的构造与析构

  1. 基类的构造析构函数不会被继承,派生类需要写自己的构造析构函数

  2. 派生类的构造函数需要给基类构造函数传递参数,注意基类成员用基类名在初始化列表进行初始化!!!

#include<iostream>
#include <string>
using namespace std;
class Base
{
public:
	int m_A;
	Base(int a) :m_A(a) {}//如果有默认构造,派生类构造时可以不传参
	void showBase()
	{
		cout << "m_A=" << m_A << endl;
	}
};
class Son :public Base
{
public:
	int m_B;
	Son(int a, int b) :Base(a), m_B(b) {}//注意基类用基类名在初始化列表进行初始化,多个基类类推
	void showSon()
	{
		cout << "m_B=" << m_B << endl;
	}
};
int main()
{
	Son s(10, 20);
	s.showBase();
	s.showSon();
	return 0;
}

类成员的标识与访问

  1. 当派生类与基类成员同名时,优先调用派生类成员,基类同名成员被屏蔽(包括重载)

  2. 通过作用域来访问


#include<iostream>
#include <string>
using namespace std;
class Base
{
public:
	int m_A;
	Base(int a) :m_A(a) {}
	void show()
	{
		cout << "基类m_A=" << m_A << endl;
	}
	void show(int a)
	{
		cout << "基类重载" << endl;
	}
};
class Son :public Base
{
public:
	int m_A;
	Son(int a1, int a2) :Base(a1), m_A(a2) {}
	void show()
	{
		cout << "派生类m_B=" << m_A << endl;
	}
};
int main()
{
	Son s(10, 20);
	s.show();//默认派生类,屏蔽了基类同名成员,包括重载
	s.Base::show();//作用域访问基类
	s.Base::show(10);//作用域访问基类重载类型
	return 0;
}

  1. 菱形继承引发的二义性问题:B1,B2继承A,C继承B1和B2,解决方法:同名屏蔽或虚函数
    A类称为虚基类,在继承前加virtual,vbptr虚基类指针virtual base pointer指向虚基数表
#include <iostream>
using namespace std;
class BaseA
{
public:
	int m_A;
	BaseA(int a) :m_A(a) {}
};
class BaseB1 :virtual public BaseA//虚继承
{
public:
	int m_B1;
	BaseB1(int a, int b1) :BaseA(a), m_B1(b1) {}
};
class BaseB2 :virtual public BaseA//虚继承
{
public:
	int m_B2;
	BaseB2(int a, int b2) :BaseA(a), m_B2(b2) {}
};
class SonC :public BaseB1, public BaseB2
{
public:
	int m_C;
	SonC(int a, int b1, int b2, int c) :BaseA(a), BaseB1(a, b1), BaseB2(a, b2), m_C(c) {}
};
int main()
{
	SonC c(30, 20, 20, 30);//B1,B2也可以初始化虚基类,但是C直接初始化优先级更高,调用了一次
	cout << c.m_A << endl;
	return 0;
}

建立对象所指定的类称为最(远)派生类
虚基类的成员由最派生类调用虚基类的构造函数进行初始化,在初始化列表调用构造函数初始化。
虚函数与纯虚函数在多态进行总结

类的继承与派生的实验结果

类型兼容规则

在这里插入图片描述

派生类的析构与构造

在这里插入图片描述

类成员的标识与访问

在这里插入图片描述

菱形继承

在这里插入图片描述


总结:通过这次试验,理解赋值兼容性原则,掌握派生类的复制构造函数的定义方法;在派生类中可以通过基类名调用基类的成员。又通过做实验加深对多重继承方式以及两个类派生出新类。在类体中声明成员函数,在类外定义成员函数等。掌握类的继承与派生的实现方法;定义合适的派生类构造函数,用于初始化基类成员和对象成员。继承是在一个已有的类上建立一个新的类,已存在的类称为基类,新建立类称为派生类。继承的方式有public,private和protected三种,默认为private.继承的方式限定了基类成员在派生类中的访问权限:类的public成员可以通过对象来访问,private成员不能通过对象和派生类访问,而protected也不能通过对象访问,但是基类protected成员可以在派生类中访问。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值