C++继承与派生

C++继承与派生详解 阅读详情


c++中的继承和派生是面向对象编程中的一个重要内容,通过继承可以实现代码的复用,同时继承也是实现多态性的基础。

一、c++继承的基本形式

class 派生类名:继承方式 基类名,继承方式 基类名

{};

继承方式主要有三种,public ,private ,protected。

缺省条件下是private继承,三种中public继承用的最多,不同的继承方式决定了子类中从基类继承过来的成员的访问属性。

public继承:

基类的public,protected成员在子类中访问属性不变,子类新增的成员函数可以直接访问,对于基类的private成员依然是基类的私有,子类无法直接进行访问。

private继承:

基类的public,protected成员转变为子类的private成员,子类新增的成员函数可以进行访问,对于基类的private成员依然是基类的私有,子类无法直接进行访问。

protected继承:

基类的public,protected成员转变为子类的protected成员,子类新增的成员函数可以进行访问,对于基类的private成员依然是基类的私有,子类无法直接进行访问。

 

private继承和protected继承的区别是private继承的子类如果继续被继承,那么这些从其分类继承得到的数据将不会被其子类继承,而protected则是可以的。

 

二、c++继承的注意事项

(1)父类的构造函数和析构函数是不会被继承的,需要重写派生类的构造函数和析构函数。

派生类的成员数据中有来自父类的成员数据,因此在写派生类的构造函数的时候需要调用其父类的构造函数。

如果派生类的成员中有成员对象,那么也需要用成员对象名来进行初始化。

这两种都是用初始化表来进行初始化工作的。

(2)派生类构造函数、析构函数的调用顺序

  • 构造函数中首先先调用各个直接基类的构造函数,之后再调用成员对象的构造函数,最后才是新增成员的初始化。
  • 对于多继承有多个基类,那么其构造函数的调用顺序是按被继承时的声明顺序,从左到右一次调用,与初始化表的顺序无关。
  • 对于成员对象的初始化也是一样,与他们的声明顺序有关,和构造函数中的初始化表的顺序无关。
  • 如果没有进行显示的调用,那么会调用其默认的构造函数
  • 子类的拷贝构造函数也要为各个直接基类的拷贝构造函数传递参数
//若 B 类是 C 类的基类,则 C 类的自定义拷贝构造函数可定义为:
C:: C (  C  &c1  )  : B ( c1 )  {   函数体   }
  • 在派生类的析构函数中不会显示调用基类的析构函数,系统会自动隐式调用,调用顺序和构造函数的调用顺序正好相反。先构造的后析构。
复制代码
class A
{
    int x1,y1;
public:
    //构造函数
    A(int a=0,int b=0)
    {
        x1=a;
        y1=b;
        cout<<"调用A的构造函数了\n";
    }

    //拷贝构造函数
    A(A& a)
    {
        x1=a.x1;
        y1=a.y1;
        cout<<"调用A的拷贝构造函数了"<<endl;
    }

    //展示内容
    void show()
    {
        cout<<x1<<" "<<y1<<endl;
    }

    //析构函数,析构函数无参数且无返回值
    ~A()
    {
        cout<<"调用A的析构函数了"<<endl;
    }
};

class B
{
    int x2,y2;
public:
    //构造函数
    B(int a=0,int b=0)
    {
        x2=a;
        y2=b;
        cout<<"调用B的构造函数了\n";
    }

    //拷贝构造函数
    B(B& b)
    {
        x2=b.x2;
        y2=b.y2;
        cout<<"调用B的拷贝构造函数了"<<endl;
    }

    //展示内容
    void show()
    {
        cout<<x2<<" "<<y2<<endl;
    }

    //析构函数,析构函数无参数且无返回值
    ~B()
    {
        cout<<"调用B的析构函数了"<<endl;
    }
};

class C:public A,public B
{
    int x3,y3;
public:
    //形参写成int x3,int y3,也就是和成员函数重名的话,内部的数据会出错,所以,不要重名,改成a,b即可
    C(int x1,int y1,int x2,int y2,int a,int b):A(x1,y1),B(x2,y2)
    {
        x3=a;
        y3=b;
        cout<<"调用C的构造函数了"<<endl;
    }

    C(C& c):A(c),B(c)
    {
        x3=c.x3;
        y3=c.y3;
        cout<<"调用C的拷贝构造函数了"<<endl;
    }

    void show()
    {
        A::show();
        B::show();
        cout<<x3<<" "<<y3<<endl;
    }

    ~C()
    {
        cout<<"调用C的析构函数了"<<endl;
    }
};



int _tmain(int argc, _TCHAR* argv[])
{
    C c1(1,2,3,4,5,6);
    c1.show();
    C c2(c1);
    c2.show();
    return 0;
}
复制代码

 

(3)赋值兼容规则

规定了基类和其子类之间的赋值规则。

对于公有派生,可以将派生类对象赋值给其基类,反之则是不被允许的。

具体体现为:

  • 基类对象=派生类对象
  • &基类对象的别名=派生类对象
  • *基类对象的指针=&派生类对象的地址

对于这种赋值,基类只能访问子类中从基类继承过来的那部分成员。

(4)继承过程中的二义性问题

继承过程中可能会出现二义性的问题。主要有两种形式的二义性。

一是在多继承中,两个父类中有同名的变量,这时如果是公有继承,那么子类中就会出现两个同名变量。解决方法有两种,一是用域作用符进行限定,二是使用同名隐藏。

二是在多继承中,两个父类的父类是同一个类,这时就需要使用虚基类的手段来进行解决。虚基类可以保证在间接继承的时候只保留一份共同基类的成员数据。

虚基类的定义:

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

{};

  • 由虚基类直接或者间接派生出来的子类都必须列出对虚基类的构造函数,若未显示列出则调用默认构造函数
  • 最终建立对象的类称为最终派生类,只在最终派生类中调用基类的构造函数,而在基类的直接派生类中不掉用基类的构造函数,这样就避免了基类成员的重复继承问题
复制代码
class B
{
    int b;
public:
    B(int x)
    {
        b=x;
        cout<<"调用了B的构造函数"<<endl;
    }

    ~B()
    {
        cout<<"调用了B的析构函数"<<endl;
    }
};

class B1:virtual public B
{
    int b1;
public:
    B1(int x,int y):B(x)
    {
        b1=y;
        cout<<"调用B1的构造函数了"<<endl;
    }

    ~B1()
    {
        cout<<"调用B1的析构函数了"<<endl;
    }
};

class B2:virtual public B
{
    int b2;
public:
    B2(int x,int y):B(x)
    {
        b2=y;
        cout<<"调用B2的构造函数了"<<endl;
    }

    ~B2()
    {
        cout<<"调用B2的析构函数了"<<endl;
    }
};


class C:public B1,public B2
{
    int c;
public:
    C(int a,int b,int c,int d):B1(a,b),B2(a,c),B(a)
    {
        c=d;
        cout<<"调用C的构造函数了"<<endl;
    }

    ~C()
    {
        cout<<"调用C的析构函数了"<<endl;
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
    C c1(1,2,3,4);
    return 0;
}
复制代码

 

C++实验: 继承与派生 C++实验: 继承与派生 1. 实验目的 (1) 了解继承在面向对象程序设计中的重要作用。 (2) 进一步掌握继承与派生的概念。 (3) 掌握通过继承派生出一个新的类的方法。 (4) 了解虚基类的作用与方法。 2. 实验内容 (1) 将程序片段用公用继承的方式补充和改写完整; (2) 将程序片段用保护继承的方式补充和改写完整; (3) 比较两种继承方式,考虑二者在什么情况下不能替代; (4) 使用多重继承方式派生出新类。 3.源代码 #include "pch.h" #include&l 阅读详情

相关推荐

C/C++ 类的继承与派生

before|正文之前: c++实验代码及学习笔记(九) 你好! 这是一个高程实验课的代码记录及学习笔记。我将记录一些重要的知识点、易错点。但是作为大学生,水平很低,敬请指点教导、优化代码。 1问题 本节课我们学习了类的继承和派生,单继承、多重继承、多继承与虚基类等知识。 这道题实际上就是对知识的直接考察,故本次笔记侧重于对知识的罗列。 2精讲 参考文章:C++ 类的继承与派生 C++中的继...

duoluka的博客 3594

C++类的继承——派生类详解

第七章 继承(类的复用)——派生类 1.单继承 格式 class <派生类名>: <继承方式> <基类名> { <成员说明表> } 继承方式可以是public,private,protected #include<iostream> using namespace std; class A { int x, y; public: void f() { cout << "这是A中的f。" << endl; } void

m0_56745306的博客 3962

10 使用继承与派生的6大要点

面向对象编程技术非常看重软件的可重用性,在C++中,可重用性是通过继承机制来实现的。继承机制允许程序员在保持原有类的数据和功能的基础上进行扩展,增加新的数据和功能,从而构成一个新的类,也称为派生类。原有类,一般称之为基类。派生类不仅拥有基类的成员,还拥有自身新增加的成员。继承与派生是C++的重要组成部分,也是C++的基础知识。掌握好了继承与派生,就对面向对象编程技术有了更深刻的理解。关于继承与派生的入门知识,这里就不赘述了,下面将介绍继承与派生相关的一些知识要点。

hope_wisdom的技术博客 2065

继承的几点注意事项(随着自己的学习更新)

1、并不是继承所有:                                                                                                             ......... 2、基于

timebomb的专栏 1817

lighttools用透镜旋转手动创建菲尼尔透镜

学过很多软件,都没有留下痕迹,很多年之后只记得学过的软件常用的一些功能,稍微难一些的再次用起需要重新学,但如果留下点痕迹,重新再用就会很快。lighttools无意之中接触了,记一点点笔记吧。...

kingsai2012的博客 4329

【实战指南】利用CAN适配器高效调试CAN总线通信

本文提供了一份利用CAN适配器高效调试CAN总线通信的实战指南。文章从硬件连接、终端电阻配置、软件参数设置等基础环节入手,详细解析了CAN适配器作为关键调试工具的工作原理与使用方法,并针对常见的通信故障提供了系统化的问题排查思路,帮助工程师快速打通通信链路,提升调试效率。

weixin_28285943的博客 412

继承与派生(11.多继承的执行顺序及构造函数的注意事项)【重点】

1.执行顺序 #include<iostream> using namespace std; class A { private: int x; public: A(int i){x=i;cout<<"it's constructing A class"<<endl;} void showA(){cout<<"it's performance showA function"<<endl;} ~A(){cout&lt

qq_45739945的博客 751

用户存续期价值评估(CLV) 一

用户存续期价值评估(CLV) 1 一. 定义 ​     用户存续期价值(Customer Lifetime Value),也可称为CLTV、LCV或者LTV,是企业对未来一个客户与其的关系所带来的净收益的预测。这个预测模型可以有不同水平的复杂度和精确度,从一个直观感觉到使用复杂的预测技术。CLV可以被简单理解为客户关系的价值,也就是未来由于与客户的关系所带...

weixin_43171270的博客 8024

C++继承和派生

C++通过类派生(classderivation)的机制来支持继承。被继承的类称为基类或超类(superclass),新产生的类为派生类(derivedclass)或子类(subclass)。基类和派生类的集合称作类继承层次结构(hierarchy)。class派生类名访问限定符基类名{private成员表1;//派生类增加或替代的私有成员public成员表2;//派生类增加或替代的公有成员protected成员表3;private。...

小程的博客 3875

AI搜索优化(GEO)实战指南:抢占智能对话流量入口

AI SEO,是针对生成式AI平台(如DeepSeek、豆包、Kimi等)的优化策略,旨在通过适配AI算法对内容的理解和引用逻辑,提升品牌在AI生成答案中的可见性与权威性,从而在对话式搜索场景中抢占流量入口。:强化内容经验性(Experience)、专业性(Expertise)、权威性(Authoritativeness)、可信度(Trustworthiness)内容需避免夸大描述,提供可验证的细节(如数据、用户评价)。

Baixue5209的博客 6774

PLc S7-200 smart如何使用Modbus 485通讯传输接收数据

西门子在 STEP 7-Micro/WIN SMART 中正式推出 Modbus RTU 主站协议库(西门子标准库指令)。使用 Modbus RTU 主站指令库,可以读写 Modbus RTU 从站的数字量、模拟量 I/O 以及保持寄存器,从而实现PLC通过modbus方式控制其他器件。提示:以下是本篇文章正文内容,下面案例可供参考。

xjbsw0的博客 6万+

C++:继承与派生

继承与派生的概念 基类与派生类 访问权限控制 派生类的构造函数、析构函数 构造函数与析构函数 duo'ji'c

qq_53826699的博客 8516

电源完整性之仿真设计原理

电源完整性(Power Integrity),简称为PI,也就是大家平常听说的PI。PCB板上的电源设计也是非常重要的,不当的设计也会引起很重要的影响。所以电源完整性PI和信号完整性SI,是我们互连设计人员应该同等重视的问题。今天整理本人接触的电源完整性PI的一些原理,从不的角度去看PI,会有不同的理解,下面开始喽!!! 提到互连的电源设计,可能首先想到的电源分配网络(Power Distribution Nets),因为互连电源会有许多种,直流DC和交流AC,还有不同的电压调节模块(VRM)与不同的负载端

刘小同学的博客 7369

CPP继承与派生

文章目录类的继承与派生类的组合类的继承单继承多继承派生类的构造函数和析构函数 类的继承与派生 类的组合 在一个类中以另一个类的对象作为数据成员(子对象),称为类的组合。 组合是横向的。 类的继承 继承是在一个已存在的类的基础上,建立一个新的类。 已存在的类称为“基类(base class)”或“父类(father class)”。 新建立的类称为“派生类(derived class)”或“子类...

SongyangJi 1298

【导航理论&实战篇】四足机器人弹簧倒立摆(SLIP)动力学模型

认知有限,望大家多多包涵,有什么问题也希望能够与大家多交流,共同成长!本文先对四足机器人动力学模型-VMC、SLIP和浮动机体模型做个简单的介绍,具体内容后续再更,其他模块可以参考去我其他文章四足机器人弹簧加载倒立摆(SLIP)动力学模型是一种用于描述和分析四足机器人在运动过程中动态特性的理论模型。这种模型将四足机器人的腿部简化为弹簧,而机器人的身体则被视为一个倒立摆,这样的抽象使得研究者能够更容易地分析和控制机器人的运动。提示:以下是本篇文章正文内容。

qq_35635374的博客 805

CodeQL查询时遇到报错:A fatal error occurred: Could not process query metadata for...如何解决?

🏆本文收录于 《全栈Bug调优(实战版)》 专栏,该专栏专注于分享我在真实项目开发中遇到的各类疑难Bug及其深层成因,并系统提供高效、可复现的解决思路和实操方案。无论你是刚入行的新手开发者,还是拥有多年项目经验的资深工程师,本专栏都将为你提供一条系统化、高质量的问题排查与优化路径,助力你加速成长,攻克技术壁垒,迈向技术价值最大化与职业发展的更高峰🚀!

**My Coding Family** 1083

c++继承与派生习题答案

1.概念填空题 1.1在C++中,三种派生方式的说明符号为 public 、 private 、 protected不加说明,则默认的派生方式为private 。 1.2当公有派生时,基类的公有成员成为派生类的 公有成员 ;保护成员成为派生类的 保护成员 ;私有成员成为派生类的 不能直接访问成员 。当保护派生时,基类的公有成员成为派生类的 保护成员;保护成员成为派生类的 保护成员 ;私有成员成为派生类的 不能直接访问成员 。 1.3 派生类的构造函数一般有3项工作要完成:首先 基类初始化 ,其次 成员

csq542586的博客 6717

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

浅谈C++的继承与派生

继承与派生的概述 派生类的构造函数与析构函数 解决继承的二义性问题 虚基类

专注技术 2737

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

C++核心编程——继承与派生

在main函数中定义对象stud1时指定了5个实参。它们按顺序传递给派生类构造函数Student1的形参(n,nam,s,a,add)。然后,派生类构造函数将前面3个(n,nam,s)

weixin_46216674的博客 1238

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

C++基础 [十二] - 继承与派生

在编程中,继承是面向对象编程(OOP)的核心概念之一。它通过让一个类(子类)继承另一个类(父类)的特性和行为,帮助我们实现代码复用、提高程序的扩展性和灵活性。那么,为什么继承在编程中如此重要呢?什么是继承假设有个App需要去获取不同类型用户的数据,并进行分类,那么就需要我们去写对应不同的类,比如说学生老师军人公司职工…………每个类都需要有名字、联系方式、家庭住址、年龄……,我们会发现这样每个类都要写一份,非常冗余,于是我们的祖师爷为了解决这个问题,设计出了继承的语法,

2402_83315537的博客 1483

C++之继承与派生

本文摘要: C++继承与派生机制通过代码复用提高了开发效率。文章系统阐述了继承的基本概念、三种继承方式(公有、私有、保护)及其访问控制特性变化,详细分析了单继承与多继承的构造/析构顺序及二义性问题。针对菱形继承导致的数据冗余,重点介绍了虚基类解决方案:通过virtual关键字实现虚继承,借助虚基表指针(vbptr)维护唯一基类实例,确保派生类仅保留一份共享数据。文章还解释了类型兼容规则(子类对象可赋给基类引用/指针)及其"切片"原理,并通过研究生助教类的具体案例,展示了如何组合运用多继承

2401_87232422的博客 907

C plus plus ——【继承与派生】

继承与派生是面向对象程序设计的两个重要特性,继承是从已有的类哪里得到已有的特性,已有的类为基类或父类,新类被称为派生类或子类。继承与派生是从不同角度说明类之间的关系,这种关系包含了访问机制,多态和重载等。多重继承是指有多个基类名标识符,其声明形式如下:class 派生类名标识符:[继承方式]基类名标识符1,基类名标识符2,…,基类名标识符n。[访问控制修饰符:][成员声明列表]声明形式中有“:”运算符,基类名标识符之间用“,”运算符分开。

weixin_44759598的博客 1435
上一篇: c++面向对象三大特征封装、继承和多态知识总结
下一篇: 在 linux 下使用 CMake 构建应用程序
csshuke
博客等级 码龄16年 1517粉丝 8原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值