一.概述

1.介绍

继承:是面向对象编程(OOP)的四大特性之一,它允许我们根据一个已有的类来定义一个新的类,称为派生类(或子类),这个已有的类称为基类(或父类)。派生类会继承基类的属性和方法。

继承的作用:实现代码的重用,提高软件开发效率

2.不能被继承的东西

  • 父类的构造函数
  • 析构函数
    • 虽然不能继承,但子类可以调用(虚析构)
  • operator=,重载的等号
    • 这些是父类专用的,子类继承过去反而会导致异常

二.继承的定义

1.继承的类型

(1)类型

父类中的私有数据子类虽可继承,但不可见,需使用公共方法调用

  • 公共继承 public (常用)

    公共继承会原样继承父类的内容,不会修改从父类继承过来数据的权限

  • 保护继承 protected

    保护继承会将从父类继承过来的数据全部设为受保护

  • 私有继承 private

    私有继承会将从父类继承过来的数据全部设为私有

(2)不同类型的权限

不同的继承类型,使得从父类继承过来的数据呈现不同的权限

image-20240315092916921

代码层面:

image-20240315092315660

(3)注意事项

  • C++的继承区分继承的方式,不同的方式对应不同的权限

  • 无论是什么继承方式,父类中的private数据在子类中虽然继承过去了,但都是不可见的,可以通过父类提供的公共方法获取

2.继承的格式&示例

格式:

class 父类{};
class 子类:继承类型 父类名{
    //子类新增数据
};

示例:

class Father{};
class Son:public Father{
    
};

三.继承中的构造和析构

1.构造&析构的顺序

(1)顺序

创建子类对象的顺序:

  • 先构造父类
  • 再构造成员
  • 最后构造子类自身

析构子类对象的顺序:

这意味着一旦子类的析构被调用,那父类的析构也必将被调用(虚析构涉及)

  • 先析构子类自身
  • 再析构成员
  • 最后析构父类

图例:

image-20240315160143109

(2)示例

代码:

#include 

using namespace std;
class Base
{
public:
    int a;
public:
    Base()
    {
        cout<<"父类默认构造"<

结果:

父类默认构造
Other默认构造
Son默认构造
Son析构
Other析构
父类析构

2.子类调用成员对象、父类的构造

无参构造自动调用、有参构造按规则用参数列表

(1)概述

默认情况下,子类是会自动调用成员对象、父类的默认构造(无参构造) 的,如果需要调用成员对象、父类的有参构造,则使用初始化列表

(2)格式

⭐ 初始化列表时,父类要写类名称,成员对象要写对象名

类名(值1,值2):成员对象1(值1),父类类名称(值2){
    //子类自身属性在此赋值
}

(3)示例

代码:

#include 

using namespace std;
class Base
{
public:
    int a;
public:
    Base()
    {
        cout<<"父类默认构造"<a = a;
        cout<<"父类有参构造"<b = b;
        cout<<"Other有参构造"<c = c;
        cout<<"Son有参构造"<

结果:

父类有参构造
Other有参构造
Son有参构造
Son析够
Other析够
父类析够

四.子父类重名成员

1.概述

当子类中成员和父类中成员重名时,默认访问的是子类中的重名成员, 而父类中的相关成员将会被屏蔽,如果想要访问父类中的重名成员,可以通过作用域 /ins>的形式进行访问。

2.访问重名对象

存在重名对象的时候,默认访问的是子类的对象

(1)格式

使用子类调用父类的成员的时候,成员名的前面添加作用域指向父类即可

子类对象.父类名::重名成员名

(2)实现

代码:

#include 
using namespace std;

class Father {
public:
    int num;
public:
    Father(){}
    Father(int num){
        this -> num = num;
    }
};

class Son:public Father{
public:
    int num;
public:
    Son(){}
    Son(int x,int y):Father(y)
    {
        num = x;
    }
};

int main(){
   Son son = Son(10, 20);
   //存在重名对象的时候,默认访问的是子类的对象
   cout << "访问子类重名成员:"<< son.num <

返回值:

访问子类重名成员:10
访问父类重名成员:20

3.访问重名函数

(1)重名函数-函数重定义

其本质就是Java中的重写父类方法

子类重新定义父类的同名函数,即子类与父类函数名相同的情况,称为函数的重定义

这个操作会使父类的所有重名函数都会被屏蔽(假设父类有重载),常常用于父类该函数不能满足需求时进行的函数重写

(2)调用父类重名函数

① 概述

虽然子类对父类的函数进行了重写,但仍然可以通过为函数名添加作用域的形式使用父类的重名函数

格式:

子类对象.父类名::重名成员名
② 示例
#include 
using namespace std;

class Father {
public:
    int num;
public:
    Father(){}
    Father(int num){
        this -> num = num;
    }
    void fun(){
        cout << "父类的函数" <
最后修改:2024 年 03 月 18 日
如果觉得我的文章对你有用,请随意赞赏