iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >一文搞懂C++中继承的概念与使用
  • 915
分享到

一文搞懂C++中继承的概念与使用

2024-04-02 19:04:59 915人浏览 安东尼
摘要

目录前言继承概念及定义继承概念继承定义继承方式父类和子类对象赋值转换继承中的作用域派生类的默认成员函数派生类的友元与静态成员继承关系单继承多继承菱形继承前言 我们都知道面向对象语言的

前言

我们都知道面向对象语言的三大特点是:**封装,继承,多态。**之前在类和对象部分,我们提到了c++中的封装,那么今天呢,我们来学习一下C++中的继承。

继承概念及定义

继承概念

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

看概念是一件很让人疑惑的东西,接下来我就来举个例子来看看继承具体是什么东西

首先我们定义两个类,一个Student类,一个Teacher类,二者都有年龄和姓名,学生有学号,老师有工号。

class Student
{
private:
    int _age;     //年龄
    string _name; //姓名
    int _stuid;   //学号
};

class Teacher
{
private:
    int _age;     //年龄
    string _name; //姓名
    int _jobid;   //工号
};

我们发现这两个类有一些重复的地方,比如年龄和姓名,这二者是他们的成员,此时代码就产生了冗余。那么我们可不可以像个方法去复用这两个成员呢?继承此时就可以发挥它的重大作用。

我们将他们重复的地方提取出来,重新定义一个Person类。而Student类和Teacher类将Person类继承下来,此时我们就实现了代码的复用。

class Person
{
protected:
	int _age;     //年龄
	string _name; //姓名
};

class Student : public Person
{
private:
	int _stuid; //学号
};

class Teacher : public Person
{
private:
	int _jobid; //工号
};

我们首先分别用Student和Teacher类来创建两个对象,来看看对象里面有什么。

int main()
{
    Teacher t;
    Student s;
    return 0;
}

此时我们可以看到我们创建的两个对象里面都含有从Person类中继承过来的 age 和 name 两个成员。

所以继承实际上是一个代码的复用,我们可以借用已完成的类的代码来完善我们需要创造的新类。

继承定义

以我们刚刚创建的Student类来举例:我们看到Person是父类,也称作基类。Student是子类,也称作派生类。

继承方式

我们在类和对象的时候介绍了三种访问限定符:public(公有),protected(保护)和private(私有)。访问限定符限定了我们在类外如何去访问类中的成员。

在继承中我们一样使用这三种限定符来限定子类该如何去访问父类的的成员,下面有一张表来表示他们的关系。

类成员\继承方式public继承protected继承private继承
父类的public成员派生类的public成员派生类的protected成员派生类的private成员
父类的protected成员派生类的protected成员派生类的protected成员派生类的private成员
父类的private成员在派生类中不可见在派生类中不可见在派生类中不可见

首先解释一下在派生类中不可见是什么意思,就如同我们在类外无法直接去修改类中的private成员一样,我们在子类中也无法直接修改父类的private成员。

如何简洁的去记这个表呢?在C++中权限的关系:public > protected > private。在继承的时候呢,父类成员的权限取的是:父类成员原本权限和继承方式中较小的那个。

比如父类的A成员原本权限为public,而子类的继承方式为private。此时A成员相对子类来说就为private成员

父类和子类对象赋值转换

子类的对象可以赋值给 父类的对象/父类的指针/父类的应用,那么是如何进行赋值的呢?形象一点来说就是切片,将子类中父类的部分切割父类。

但我们无法反过来,将父类对象赋值给子类对象。

继承中的作用域

在继承体系中父类和子类都有独立的作用域,如果子类和父类中有同名的成员,子类成员将屏蔽对父类成员的直接访问,这种情况叫隐藏,也叫重定义。

下面还是用我们的Person类和Student类来举个栗子,我们分别在Person类和Student类中加入一个print函数,通过打印内容来区分调用的为哪一print函数。

class Person
{
protected:
    int _age;
    string _name;

public:
    void print()
    {
        cout << "Person"<< endl;
    }
};

class Student : public Person
{
private:
    int _stuid; //学号
    public:
    void print()
    {
        cout << "Student" << endl;
    }
};

接下来我们创建一个对象然后来试一下结果。

int main()
{
    Student s;
    s.print();
    return 0;
}

我们可以看到我们调用的为Student中的print函数。此时子类的print函数已经对父类的print函数进行了重定义。重定义不代表子类无法去调用父类的同名函数,只是不那么直接而已。使用下面这种方法我们就可以调用父类中的同名函数。

int main()
{
    Student s;
    s.Person::print();
    return 0;
}

通过指定类域,我们就可以去调用父类的print函数。但在实际中最好不要去定义同名函数以免带来问题。

派生类的默认成员函数

首先我们来回顾一下有哪几个默认成员函数。

那么在子类中,这些默认成员函数是怎么生成的呢?

1.子类的构造函数必须调用父类的构造函数初始化父类的那一部分成员。如果父类没有默认的构造函数,则必须在派生类构造函数的初始化列表中显式调用。还是用我们的Person类和Student类举例。

情况一:有默认构造函数

class Person
{
protected:
    int _age;
    string _name;

public:
    Person()
    {
        cout << "Person" << endl; //调用就打印
    }
};

class Student : public Person
{
private:
    int _stuid; //学号
public:
    Student()
    {
        cout << "Student" << endl; //调用就打印
    }
};

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

情况二:无默认构造函数

class Person
{
protected:
    int _age;
    string _name;

public:
    Person(int age, string name)
    {
        cout << "Person" << endl;
    }
};

class Student : public Person
{
private:
    int _stuid; //学号
public:
    Student()
        : Person(19, "wanku") //无默认构造,此时我们需要在初始化列表中初始化
    {
        cout << "Student" << endl;
    }
};

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

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

2.子类的拷贝构造函数必须调用父类的拷贝构造完成父类的拷贝初始化化。

class Person
{
protected:
    int _age;
    string _name;

public:
    Person(int age = 10, string name = "wanku")
    {
        cout << "Person" << endl;
    }

    Person(const Person &p)
        : _age(p._age), _name(p._name)
    {}
};

class Student : public Person
{
private:
    int _stuid; //学号
public:
    Student()
    {
        cout << "Student" << endl;
    }

    Student(const Student &s)
        : Person(s) , _stuid(s._stuid)
    {}
};

有些朋友可能会疑惑,在Person类中的拷贝构造函数参数明明是Person类,为什么我们的Student类可以传过去呢?那是因为我们刚刚讲的切片原理,当我们把子类对象传过去时,编译器会进行切分,然后再传给父类。

3.派生类的operator=必须要调用基类的operator=完成基类的复制。(原理和拷贝构造大体相似,值得注意的是:当我们在子类直接想去调用父类的operator= 时,会发生重定义,使用时记得加上父类的作用域)

4.在继承中一个对象的历程如下:父类的构造函数 –> 子类的构造函数 –> 子类的析构函数 –> 父类的析构函数。这个过程相当于把这些行为存在一个栈中,然后再把行为从栈中拿出来一般

派生类的友元与静态成员

父类的友元不是子类的友元。(你爸爸的朋友不一定是你的朋友)

父类中有一个静态成员,那么子类和父类共用一个静态成员。(静态成员并不存在对象中,只开辟一个空间,所以只能共用一个)

继承关系

单继承

一个子类只有一个直接父类。

多继承

一个子类有两个及以上的父类

菱形继承

多继承的一种特殊情况

以上就是一文搞懂C++中继承的概念与使用的详细内容,更多关于C++继承的资料请关注编程网其它相关文章!

--结束END--

本文标题: 一文搞懂C++中继承的概念与使用

本文链接: https://www.lsjlt.com/news/164878.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 一文搞懂C++中继承的概念与使用
    目录前言继承概念及定义继承概念继承定义继承方式父类和子类对象赋值转换继承中的作用域派生类的默认成员函数派生类的友元与静态成员继承关系单继承多继承菱形继承前言 我们都知道面向对象语言的...
    99+
    2024-04-02
  • 一文带你搞懂Maven的继承与聚合
    目录一、继承二、继承关系实施步骤三、聚合与继承的区别一、继承 我们已经完成了使用聚合工程去管理项目,聚合工程进行某一个构建操作,其他被其管理的项目也会 执行相同的构建操作。那么接下来...
    99+
    2024-04-02
  • C++深入探究继承的概念与使用
    目录1、概念及定义1.1 概念1.2 定义2、class与struct的区别3、赋值兼容规则4、继承中的作用域问题5、派生类(子类)的默认成员函数5.1 构造函数5.2 拷贝构造函数...
    99+
    2024-04-02
  • C++ 超详细梳理继承的概念与使用
    目录继承的概念及定义继承的概念继承定义定义格式继承关系和访问限定符继承基类成员访问方式的变化基类和派生类对象赋值转换继承中的作用域派生类的默认成员函数继承与友元继承与静态成员复杂的菱...
    99+
    2024-04-02
  • C++中继承的概念和定义
    目录1.继承的概念及定义1.1继承的概念1.2继承的定义格式1.3继承基类成员访问方式的变化(1)公有继承(2)保护继承(3)私有继承1.4总结2.基类和派生类对象赋值转换3.继承中...
    99+
    2024-04-02
  • C++数据结构继承的概念与菱形继承及虚拟继承和组合
    目录继承的概念继承的定义基类和派生类对象之间的赋值转换继承中的作用域派生类的默认成员函数继承中的两个小细节继承和友元继承和静态成员单继承和多继承(菱形继承)虚拟继承概念虚拟继承的原理...
    99+
    2024-04-02
  • 一文读懂C++中的继承之菱形继承(案例分析)
    目录前言一、什么是多继承?1.单继承2.多继承二、菱形继承1.虚基类的引入2.虚基表的引入总结前言 我们上一篇说了世间万物都有一个继承体制,或多或少子类继承了父类的某些特征,但大多都...
    99+
    2024-04-02
  • 一文搞懂JavaScript中最难理解概念之一的闭包
    目录一、闭包的概念二、怎么实现闭包三、闭包的用途1.封装私有变量2. 做缓存3. 模块化编程(实现共有变量)四、闭包的缺点五、最后的话一、闭包的概念 当通过调用外部函数返回的内部函数...
    99+
    2023-05-14
    JavaScript闭包实现 JavaScript闭包应用 JavaScript闭包
  • C++数据结构继承的概念与菱形继承及虚拟继承和组合分析
    这篇“C++数据结构继承的概念与菱形继承及虚拟继承和组合分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“C++数据结构继承...
    99+
    2023-06-29
  • C++中的继承问题(继承基本概念、菱形虚拟继承的对象模型)
    目录一、继承的概念与定义格式概念及定义格式二、赋值兼容规则三、继承中的作用域四、子类的默认成员函数构造函数拷贝构造函数赋值运算符重载析构函数构造和析构函数调用顺序五、继承与友元、静态...
    99+
    2023-02-05
    C++的继承 继承基本概念 菱形虚拟继承
  • 详解C++中单继承与多继承的使用
    目录前言1.继承的概念和定义(1)继承的概念(2)继承的定义方法(2)继承后子类的成员类型2.基类与派生类的赋值转换(1)派生类赋值给基类(2)基类给派生类3.继承中的作用域(1)隐...
    99+
    2024-04-02
  • Python 继承与多态:从概念到应用,一网打尽
    什么是继承? 继承是面向对象编程中一个基础的概念,它允许一个类(子类)继承另一个类(父类)的特性。子类继承父类的属性和方法,并可以覆盖父类的方法以实现不同的行为。这有助于代码重用,减少重复代码并增强可扩展性。 继承的语法 在 Pytho...
    99+
    2024-02-19
    Python 继承 多态 代码重用 可扩展性
  • C++中单继承与多继承如何使用
    今天小编给大家分享一下C++中单继承与多继承如何使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。前言C++的继承机制相对其...
    99+
    2023-06-30
  • java中接口与继承的概念和实现方法
    本篇内容主要讲解“java中接口与继承的概念和实现方法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“java中接口与继承的概念和实现方法”吧!目录JAVA接口的概念接口的代码实现定义关键字:in...
    99+
    2023-06-20
  • 一文搞懂Python中函数的定义与使用
    目录函数的定义和调用无参函数有参函数带有返回值的函数函数与循环结合与while循环结合与for循环结合函数的分类内置函数自定义函数函数的嵌套调用函数的嵌套定义函数的定义和调用 函数的...
    99+
    2024-04-02
  • 一文搞懂Java ScheduledExecutorService的使用
    目录一、创建ScheduledExecutorService对象二、ScheduledExecutorService方法三、固定速率和固定延时的区别1. 固定速率2. 固定延时四、调...
    99+
    2022-11-13
    Java ScheduledExecutorService使用 Java ScheduledExecutorService
  • 一文搞懂C++多态的用法
    目录前言1.多态的概念2.C++中多态的分类(1)静态多态(2)动态多态3.多态的构成条件(1)举例(2)两个概念(3)多态的构成条件4.虚函数重写的两个例外(1)协变(2)析构函数...
    99+
    2024-04-02
  • 一文搞懂C++中string容器的构造及使用
    目录string容器string基本概念string构造函数string赋值操作string拼接操作string查找替换string字符串比较string字符读取string插入和删...
    99+
    2024-04-02
  • 一文搞懂JavaSPI机制的原理与使用
    目录SPI 概念举个栗子第一步第二步第三步第四步原理常用的框架优缺点优点缺点Java 程序员在日常工作中经常会听到 SPI,而且很多框架都使用了 SPI...
    99+
    2024-04-02
  • 一文搞懂 React 18 中的 useTransition() 与 useDeferredValue()
    目录前言什么是Concurrent React?设置项目实现 useTransition()isPending 是做什么的?前言 React 18 引入了一个关键的新概念,称为&ld...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作