C++继承(从0开始)

在c++使用类的时候,往往会出现不同类需要有相同的参数或者函数,于是为了发扬最少代码做最多事的优良传统,C++可以继承。

好,话不多说,直接开始学习。

首先要了解继承目的:类之间的复用

1.继承的概念

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

定义格式:

Preson既是父类也叫基类,Student既是子类也是派生类。

继承方式:  public继承

                     Protected继承

                     Private继承

访问限定符:public访问

                         Protected访问

                         Private 访问

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

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

1.3.实际上面的表格总结发现,基类的私有成员在子类都是不可见的。基类的其他成员在子类的访问方式==Min(成员在基类的访问限定符,继承方式)两者取最严格public>protected>private。

1.4.class默认的访问限定符:private。Struct默认的访问限定符是public。(最好标明)

1.5.类中的私有成员和保护在当前类没有差别,在继承的后的子类中有影响,私有的成员在子类中无法访问。

1.6.private私有继承:基类的可继承成员都成了直接派生类的私有成员,无法进一步继承。相比之下,protected保护继承:基类的可继承成员成了直接派生类的保护成员,可以继续继承。

2.基类和派生类的赋值兼容规则

2.1.子类对象可以赋值给父类对象/指针/引用。(切片)反过来一般不行,父类传给子类会少传,报错,除非强转父类为子类类型:父类是指向子类的:(Student*)ptr(#注意子类赋值给父类,父类依然是父类,不会改变类型,不能访问子类的成员,类比数据类型的强转)

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

2.3.基类的指针可以通过强制类型转换赋值给派生类的指针。但必须是基类的指针对象时才是安全的。这里基类如果是多态类型,可以使用RTT(Run-Time Type information)的dynamic cast来进行识别后安全转换。

3.继承中的作用域

3.1.在继承体系中基类派生类都有独立的作用域

3.2.子类和父类中有同名成员时,不会报错,因为有不同的作用域,子类成员将屏蔽对父类同名成员的直接访问,这种情况叫隐藏(#注意不是重载!重载必须在同一定义域。隐藏是指1.变量名相同or2.如果是成员函数的隐藏只需函数名相同,参数无要求),也叫做重定义。在子类成员函数中,可以使用基类::基类成员 显示访问。

3.3.实际使用中在继承体系中最好不要定义同名成员。

4.继承中的默认成员函数

4.1.派生类的构造函数必须调用基类的构造函数来初始化从基类继承的那一部分成员,如果基类没有默认的构造函数,则必须在派生类构造函数的初始化列表阶段显示调用。(什么时候用初始化列表阶段,1.有数据成员是引用类型2.当有数据成员是常量(const)时3.当父类的构造函数有参数时4.当成员变量所属类型的构造函数有参数时)。

4.2.派生类的拷贝构造函数必须调用基类的拷贝构造函数完成基类的拷贝构造。

4.3.派生类的operator=必须要调用基类的operator=来完成基类的复制。

4.4.派生类的析构函数会在被调用完成后自动调用基类的析构函数清理基类成员。这样才保证先清理派生类对象再清理基类成员的顺序。

4.5.派生类对象初始化:先调用基类构造函数再调派派生类构造函数。

4.6.派生类对象析构清理要先调用派生类析构函数再调基类的析构函数。

 

子类的析构函数和父类的析构函数构成隐藏,因为他们的名字会被编译器统一处理成destructor(与多态有关)

析构函数不需要显示调用,为保证析构顺序,默认就行

#如何设计一个不能被继承的类:

构造函数私有化A就不能被继承。

class A
{
private:
    A()
    {};
};
class B :public A
{};

5.多重继承

5.1.多个基类继承来的成员有同名现象,可以使用类名限定符“::”来进行区分。但是,有个前提:这些基类不是从一个共同的基类派生来的。如果不具备这个前提条件,在访问同名成员时会出现问题。

 

5.2.内存中实际上存在两个基类Person的对象,一个是由Student这一派生分支产生,另一个是由Teacher的派生分支产生的。

               Person::id   =10001;  // 二义性错误

5.3.无法传递给系统足够的信息,系统无法知道该语句到底要访问哪一个id。

###特别强调一定不要使用菱形继承!!!会产生数据冗余和二义性!!!

                                                  总之菱形继承就是原罪!!!

6.虚基类

6.1.当某类多个直接基类是从一个共同基类派生而来时,这些直接基类中从上一级基类继承来的成员在内存中存在多个副本。在编程时,只需使用多个副本的任意一个。

6.2.C++语言允许程序中只建立公共基类的一个副本,将直接基类的共同基类设置为虚基类(virtual base class),这时从不同路径继承过来的该类成员在内存中只拥有一个副本。

6.3.虚基类的声明是在派生类继承基类时定义的,其语法形式如下:

    class 派生类名:virtual [继承方式] 基类名

6.4.由于派生类的对象中只有一个虚基类子对象。为保证虚基类子对象只被初始化一次,这个虚基类构造函数必须只被调用一次。

6.5. 规定将在建立对象时所指定的类称为最直接派生类。虚基类子对象是由最直接派生类的构造函数通过调用虚基类的构造函数进行初始化的。

6.6.只有用于建立对象的那个派生类的构造函数调用虚基类的构造函数,而该派生类的基类中所列出的对这个虚基类的构造函数调用在执行中被忽略。

这是我第二次写博客,可能写的不好,我上传完发现有水印而且有点图片画质降低啦,大家多担待,如果有错误或者可以改进的地方,希望大家多多指出,希望我们在代码的海洋里遨游!!!

少年没有乌托邦,心向远方自明朗

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

头发尚存的猿小二

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值