C++ 继承

目录

一、继承的概念及定义

1.1 继承的概念

1.2 继承方式和访问限定符

1.3 数据成员和成员函数是如何继承的

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

三、继承中的作用域

四、派生类的默认成员函数(构造,析构,拷贝构造,operator=...)

五、继承与友元

六、继承与静态成员

七、菱形继承与菱形虚拟继承

菱形继承:

 菱形虚拟继承:

虚拟继承:

虚拟继承解决数据冗余和二义性的原理

追加:


一、继承的概念及定义

1.1 继承的概念

继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。以前我们接触的复用都是函数复用,继承是类设计层次的复用。  (copy的)

1.2 继承方式和访问限定符

访问限定符即声明此类的成员对于类外访问的权限设置,有public访问 protected访问 private访问 (访问限定符)
继承方式分为public继承,protected继承,private继承

 上图看上去很多继承方式和访问限定符的组合很复杂,但是事实上是有规律的。

1. 继承方式相当于限定了成员的最高访问权限,若public继承,则基类的成员访问权限在派生类中不变。若protected继承,则限定了派生类继承父类成员时最高访问权限为protected,则原本public的会变为protected访问权限,protected的不变。private继承同理。

2. 总结第一条:基类除了private成员在派生类的访问权限为在基类的访问权限和继承方式中权限更小的那个。

3. 明确什么是不可见:基类的private成员无论什么继承方式,在派生类中均不可见。这里的不可见是指基类的私有成员还是被继承到了派生类对象中,但是语法上限制派生类对象不管在类里面还是类外面都不能去访问它。

4. 基类的private成员在派生类中是不能被访问的,如果基类成员不想在类外直接被访问,但需要在 派生类中能访问,就定义为protected。可以看出protected限定符是因继承才出现的。

5. 使用关键字class时默认的继承方式是private,使用struct时默认的继承方式是public,不过最好显式的写出继承方式。

6. 实际运用中,public继承方式+public,protected访问限定符是最合适的。(绝大多数情况!)

7. 访问限定符这个东西,是为了限定在类外访问此成员时可以访问or不能访问,这里的类外包括子类,因为private成员继承下去之后,子类不能访问(隐身了)。而同类类内的访问和调用不受访问限定符的影响。 

1.3 数据成员和成员函数是如何继承的

基类的所有数据成员,派生类中都会继承,也就是每一个派生类的实例化对象中都有一部分基类的数据成员,再加上派生类自己定义的数据成员组合成派生类对象。

而成员函数:成员函数是存储在代码段的,也仅有一份,是属于基类的,只是public 和 protected成员函数,可以在派生类内调用。并且类外调用基类的成员函数时,成员函数的this指针默认是const 基类*类型!

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

1. 派生类对象 可以赋值给 基类的对象 / 基类的指针 / 基类的引用。这里有个形象的说法叫切片。寓意把派生类中父类那部分切来赋值过去。

2. 基类对象不能赋值给派生类对象。

3. 派生类对象赋值给基类对象,调用基类的operator=(const 基类& x);正是因为基类引用可以引用派生类对象,这里的赋值才可以的。

4. 派生类对象地址赋值给基类指针,可以理解为指针指向派生类中基类的那一部分。引用可以理解为引用派生类中基类的那一部分。因此,基类指针或引用只能访问那些基类有的,派生类继承了的成员,不能访问派生类自己的。

5. 基类的指针或者引用可以通过强制类型转换赋值给派生类的指针或者引用(必须强制类型转换)。但是必须是基类 的指针是指向派生类对象时才是安全的。

5. 这里实际上意义是非常大的,因为多态的基础就是派生类对基类赋值的支持。

三、继承中的作用域

1. 在继承体系中基类和派生类都有独立的作用域。是两个相互独立的类域。

2. 如果基类和派生类中有同名的成员,则派生类成员将屏蔽对基类同名成员的直接访问,这种情况叫隐藏, 也叫重定义。(可以使用 基类::基类成员 指定类域的方式显式访问)

3. 如果是成员函数的隐藏,只需要函数名相同就构成隐藏。

4. 基类和派生类同名的成员函数构成隐藏,但是不构成重载,因为不是同一个作用域。

4. 注意在实际继承体系里面最好不要定义同名的成员。

示例代码:

class Person
{
public:
	void print()
	{
		cout << "name:" << _name << endl;
		cout << 
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值