C++ C4 -继承和派生-继承中的构造与析构-派生类中的static关键字-多继承

继承和派生

继承可以用来干什么:

  1. 可以在已有的类的基础上添加新的变量;
  2. 可以在已有的类的基础上添加新的功能(函数);
  3. 可以修改类的方法(不常用)::例如车是父类,衍生出汽车 大巴车两个子类;在父类中有一个开车的方法;但是对于两个字类来讲,开车的方法不同。所以会设计方法的重写(修改类的方法);
    什么时候用继承?
  4. 创建一个新类时,这个类和现有的类相似(只是多出一些变量或函数的时候)例如:同样是车的例子,我先有一个车的类,然后要定义一个轿车的类,发现轿车和车有相似(都是四个轮子,都是用方向盘的等等)
  5. 当你创建多个类时,发现有很多类似的成员函数或者成员变量。例如:我先定义了,汽车,跑车,大巴车三个类,发现他们都是四个轮子,都是交通工具,都是一个司机等等相同的成员变量或函数,那么就可以将这写相似的提取出来作为一个 车 类,然后这三个类再去继承他,这样可以节省代码。
    继承权限
    继承的声明是:
    class 派i类名:<继承权限> 基类名{ };
    继承默认的权限和封装一样为 private
    public继承方式:
    1)基类中所有 public 成员在派生类中为 public 属性;
    2)基类中所有 protected 成员在派生类中为 protected 属性;
    3)基类中所有 private 成员在派生类中不能使用。
    protected继承方式
    1)基类中所有 public 成员在派生类中为 protected 属性;
    2)基类中所有 protected 成员在派生类中为 protected 属性;
    3)基类中所有 private 成员在派生类中不能使用。
    private继承方式
    1)基类中所有 public 成员在派生类中均为 private 属性;
    2)基类中所有 protected 成员在派生类中均为 private 属性;
    3)基类中所有 private 成员在派生类中不能使用。
    有几点说明:
  1. 基类成员在派生类中的访问权限不得高于继承方式中指定的权限。例如,当继承方式为 protected 时,那么基类成员在派生类中的访问权限最高也为 protected,高于 protected 的会降级为 protected,但低于 protected 不会升级。再如,当继承方式为 public 时,那么基类成员在派生类中的访问权限将保持不变。
    也就是说,继承方式中的 public、protected、private 是用来指明基类成员在派生类中的最高访问权限的。
  2. 不管继承方式如何,基类中的 private 成员在派生类中始终不能使用(不能在派生类的成员函数中访问或调用)。
  3. 如果希望基类的成员能够被派生类继承并且毫无障碍地使用,那么这些成员只能声明为 public 或 protected;只有那些不希望在派生类中使用的成员才声明为 private。
  4. 如果希望基类的成员既不向外暴露(不能通过对象访问),还能在派生类中使用,那么只能声明为 protected。
    注意:我们这里说的是基类的 private 成员不能在派生类中使用,并没有说基类的 private 成员不能被继承。实际上,基类的 private 成员是能够被继承的,并且(成员变量)会占用派生类对象的内存,它只是在派生类中不可见,导致无法使用罢了。private 成员的这种特性,能够很好的对派生类隐藏基类的实现,以体现面向对象的封装性
class Base
{
private:
	int a;
protected:
	int b;
public:
	int c;	
	Base(int a,int b,int c):a(a),b(b),c(c){};
}
class Base1:protected Base
{
public:
	void show()
	{
		cout<<"a"<<a<<endl;//error  a是private不可访问
	}
}
int main()
{
	Base1 b;
	b1.b;//error protected继承以后b变量还是protected属性
	b1.c;//error protected继承以后c变量变成了protected属性
	return 0;
}

继承中的构造与析构

私有继承-组合对象的区别
相同点:都可以表示,A中有B的关系
不同:私有继承中派生类可以访问基类的protected成员;
可以重写基类的虚函数
组合对象不可以,
尽可能使用组合对象,万不得已在使用私有继承
继承中的构造与析构调用原则
1、子类对象在创建时会首先调用父类的构造函数
2、父类构造函数执行结束后,执行子类的构造函数
3、当父类的构造函数有参数时,需要在子类的初始化列表中显示调用
4、析构函数调用的先后顺序与构造函数相反
继承和组合对象混搭时的构造与析构调用原则
1.先构造父类,再构造成员变量、最后构造自己
2.先析构自己,在析构成员变量、最后析构父类

成员覆盖问题

成员覆盖:
派生类中出现与基类中继承的成员变量名称相同的成员,会覆盖继承过来的成员(默认调用派生类中同名成员)
如何调用被覆盖成员:
1.类名::成员变量
2.对象名.类名::成员函数

派生类中的static关键字

1.基类定义的静态成员,将被所有派生类共享
2.根据静态成员自身的访问特性和派生类的继承方式,在类层次体系中具有不同的访问性质 (遵守派生类的访问控制)
3.访问方式 类名 :: 成员
对象.成员(对象可以是 该类定义的任何一个对象)
共享机制 : 任意对象共享 + 派生类共享
!!仍然要注意static定义的成员变量要在类外定义

多继承

多继承:
class 派生类名:<继承权限> 基类名,<继承权限> 基类名…
构造函数:
先构造基类后构造派生类;
基类构造顺序根据派生时顺序决定的;
多继承中的冲突
多继承中的名称冲突:
如果不同基类中出现相同的成员变量或者成员函数
那么在派生类中或外部调用时候 会出现二义性.
需要明确一下是调用那个类中的成员 用"类名::"处理
注意:在继承关系中,域解析符不能连用
多继承的二义性
如果一个派生类从多个基类派生,而这些基类又有一个共同的基类,则在对该基类中声明的名字进行访问时,可能产生二义性
原因,因为一个基类被继承多次的时候,会创建多个副本,出现名称冲突
解决:
虚继承(virtual)
当将一个基类声明为虚基类的时候,不管他在派生类中被继承多少次,该基类中的成员在该派生类中始终都只有一个副本。
声明方法:
class 派生类名:virtual <继承权限> 基类名
加入虚继承以后构造顺序
先构造虚继承的基类,然后是其他基类,最后是自己
注意!虚继承只会被构造一次,之后不会再被构造

class Base1  
class Base2
class Derived1:public Base2,virtual public Base1
class Derived2:public Base2,virtual public Base1
class Top:public Derived1,virtual public Derived2

base1①  base2②  Derived1③ Derived2④  TOP⑤

构造顺序为1 2 4 2 3 5

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值