c++ 继承(上)

一.继承是什么

继承实际上是一种关系的复用,比如在现实生活中,学生属于人类,学生就继承了人类的所有特性,大学生属于学生,那么大学生也就继承了学生的额所有特性

二.继承的表示

格式 : 

class 类名 : 继承方式(public.private,protected) (被继承的)类名

被继承的类(Person)称为父类/基类,继承的类(Student)称为子类/派生类

class Person
{
protected:
	string _name;
};

class Student : public Person
{
protected:
	int _stunum;
};

int main()
{
	Student s1;
	return 0;
}

三.继承的意义

继承即复用,父类的所有成员都会变成子类的一部分


Person中的_name成员也成为了Student s1的一部分,值得说明的是,这里编译器为了使我们看的更清楚一些,在s1下面表示出Person下有一个_name,实际上,在子类中,父类的成员直接存储在子类成员的前面,并不会存储父类的类名

四 . 三种继承方式 public,private,protected


注意 : 当成员是私有的,在子类中都不可见,不可见是指称为子类的一部分,但是我们不可以访问

1)父类成员访问限定符对继承的影响

当父类的成员是共有的或者保护的,那么在子类中,这些继承来的成员是可见的(可访问的)

当父类的成员是私有的,那么在子类中,这些继承来的成员是不可见的(不可访问的)

如 : 当我们把Person类中的_name定义为私有成员时,编译时,编译器会告诉我们,无法访问私有成员


所以,当我们需要在子类中访问父类成员时,必须把父类的成员定义成共有或者保护的.

为了实现我们复用的目的,在继承的时候保护限定符用的多一些,很少用私有限定符

2)子类的继承方式对继承的影响

当我们使用共有继承时,子类继承来的成员的访问限定不变(和父类一样)

当我们使用私有继承(保护继承)时,子类继承来的成员的访问限定变为私有(保护)

如 : 当我们用保护的方式继承父类(Person)时,在main函数中,调用Student的公有成员,编译器也会报错


3)公有继承 , 私有继承和保护继承的区别:

如果Student是公有继承Person,那么在Student中,成员的访问限定不变

如果Student是保护继承Person,那么当学生类再次被大学生类所继承的时候,在大学生类里,学生类的成员是可见的

如果Student是私有继承Person,那么在下面的Student的子类中,Student类的成员是不可见的

4)默认继承方式

对于class,继承方式不写的话,默认为私有继承

对于struct,继承方式不写的话,默认为公有继承

五.复制兼容问题(切片)

1)了解 is-a 和 has-a


2)切片


注意:

a)切片的前提是 is-a 的关系,像如下的 has-a 的关系是不可以切片的


b) 在切片的过程中并没有类型的转换,是天然的切割,只是把父类需要的东西从子类中取出来;

所以Person& p = s; 也是可以发生的,因为他并不是隐式类型转换,没有生成具有常性的临时变量,所以p可以直接成为s中一部分的别名

切片总结:

a)子类对象可以赋值给父类的对象/父类的引用/父类指针    ->    建立在 is-a的基础上

b)父类对象不可以赋值给子类对象    ->    父类比子类少一部分,无法满足子类的需要

c)父类指针/引用不能复制给子类的指针/引用(可以强转)    ->    

    Student* s = (Student*)&p

    Student& s = (Student&)p;

    虽然可以通过以上方式强转,但是会出现越界情况,在上面代码中,父类只有_name一个成员,在32为平台下只有4个字节,但是强转为Student类的时候,编译器就会向后看4个字节去找_stunum,但是实际上并没有后面4个字节的空间,就会产生越界


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值