c++第七天 继承与派生2

news2025/6/12 8:20:04

这一篇文章主要内容是

派生类构造函数与析构函数

在派生类中重写基类成员

以及多继承

第一部分:派生类构造函数与析构函数

        当创建一个派生类对象时,基类成员是如何初始化的?

1.当派生类对象创建的时候,基类成员的初始化顺序

(1)先初始化基类部分,再初始化派生类自己的成员

(2)也就是说,派生类对象在构造时,首先会调用基类的构造函数,把基类的成员变量初始化好,然后才会执行派生类自己的构造函数与成员初始化。

那么一般是什么样子的呢?

class Base {
public:
    Base() { cout << "Base构造" << endl; }
    ~Base() { cout << "Base析构" << endl; }
};

class Derived : public Base {
public:
    Derived() { cout << "Derived构造" << endl; }
    ~Derived() { cout << "Derived析构" << endl; }
};

int main() {
    Derived d;
    return 0;
}

  是这样的格式,首先进行的是初始化工作,然后再进行派生。

这里输出的结果是

Base构造
Derived构造
Derived析构
Base析构

第二个问题:当派生类对象销毁时,析构的顺序是什么样子的?

先析构派生类自己的成员,再析构基类部分。

也就是说,派生类对象销毁时,先执行派生类的析构函数,然后再自动调用基类的析构函数。

总结口诀:

构造顺序:先基类,后派生

析构顺序:先派生,后基类 

①在创建派生类对象时,首先会调用基类的构造函数,然后再调用派生类的构造函数。

#include<iostream>

class Base{
public:
    Base(){
        std::cout << "Base constructor called" << std::endl;
    }
};

class Derived : public Base{
public:
    Derived(){
        std::cout << "Derived constructor called" << std::endl;
    }
};

int main()
{
    Derived d;
    return 0;
}

只要创建派生类对象,必然会调用基类构造函数

②当基类的构造函数需要参数时,派生类的构造函数需要显式地调用基类的构造函数并传递参数。

#include<iostream>
using namespace std;

class Base{
public:
    Base(int value){
        std::cout << "Base constructor called with value" << value << std::endl;
    }
};

class Derived : public Base{
public:
    Derived(int baseValue,int derivedValue) : Base(baseValue){
        std::cout << "Derived construtor called with value" << derivedValue << std::endl;
    }
};
int main()
{
    Derived d(10,20);
    return 0;
}

③派生类构造函数中初始化列表的作用和使用方法。初始化列表可以用于调用

a.基类的构造函数,b.对象成员的构造函数,c.派生类自身的成员变量。

#include <iostream>
using namespace std;

class Base {
public:
	Base(int d):data(d) { cout << "Base" << endl; }
	int getData() {
		return data;
	}
protected:
	int data;
};

class Derived : public Base {
private:
	Base b;         //对象成员
	int c;
public:
	Derived():Base(0),b(1) { cout << "Derived" << endl; }
	Derived(int x) :Base(x),b(2*x),c(3*x) {  }
};

int main()
{
	Derived d(10);
	cout << d.getData() << endl;
	return 0;
}

④默认构造函数和自定义构造函数。如果基类有默认构造函数,派生类的构造函数可以不显式调用基类的构造函数,编译器会自动调用基类的默认构造函数。但如果基类没有默认构造函数,派生类的构造函数必须显式调用基类的构造函数。

⑤析构函数的调用顺序:在销毁派生类对象时,首先会调用派生类的析构函数,然后再调用基类的析构函数。(一句话:和构造的顺序相反)

#include <iostream>
using namespace std;

class Base {
public:
	Base(int d):data(d) { cout << "Base" <<data<< endl; }
	int getData() {
		return data;
	}
	~Base() { cout << "Base析构" <<data<< endl; }
protected:
	int data;
};

class Derived : public Base {
private:
	Base b;//对象成员
	int c;
public:
	Derived():Base(0),b(1) { cout << "Derived" << endl; }
	Derived(int x) :Base(x), b(2 * x) { c = 3 * x; }
	~Derived() { cout << "Derived析构" << endl; }
};

int main()
{
	Derived d(10);
	cout << d.getData() << endl;
	return 0;
}

输出结果

      1. 在派生类中重写基类成员

重写是指在派生类中定义一个与基类中同名、同参数列表、同返回类型的成员函数,以此来改变基类函数的行为。

重载是在同一类中,函数名相同但参数列表不同。

#include<iostream>
using namespace std;

class Base{
public:
    void display(){
        std::cout << "This is the Base222 class." << std::endl;
    }
};

class Derived : public Base{
public:
    void display(){
        cout << "This is the Base class" << endl;
    }

};

int main()
{
    Derived d;
    d.display();
    return 0;
}

重写的函数(派生类中)必须与基类函数的函数名、参数列表和返回类型完全相同。否则就会变成重载(要求参数不同)重写函数的访问权限可以不同,但通常建议保持一致。例如,基类函数是 public,派生类重写函数也用 public。

  1. 多继承

单继承:一个派生类只能有一个直接基类;当需要组合多个不同类的特性时,单继承无法直接实现,需多继承。即多继承具有更强的代码重用的能力。

class 派生类 : 继承方式 基类1, 继承方式 基类2, ... {

    // 成员声明

};

多继承下的构造函数与析构函数的调用顺序

 

#include<iostream>
using namespace std;

class Speakable{
public:
    Speakable() {cout << "Speakable构造" << endl;}
    void speak() {cout << "Speaking..." << endl;}
};

class Moveable{
public:
    Moveable() {cout << "Moveable构造" << endl;}
    void move() {cout << "moving..." << endl;}
};

class Robot : public Speakable,public Moveable{
public:
    Robot() : Moveable(),Speakable() {}
};

int main()
{
    Robot r;
    r.speak();
    r.move();
    return 0;
}

多继承的二义性:

#include<iostream>
using namespace std;
class A {
	public:
		void f() { cout << "A"; }
};
class B {
public:
	void f() { cout << "B"; }
};

class AB :public A, public B {
    public:
        //void f() { cout << "AB"; }
};
int main()
{
    AB ab;
	ab.B::f();
    ab.A::f();
	return 0;
}

错误提示:对“f”的访问不明确

解决的办法:就是在成员函数的前面加上类名::,说明使用从哪个基类继承的成员函数。

ab.B::f();

ab.A::f();

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2407092.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

淘宝扭蛋机小程序系统开发:打造互动性强的购物平台

淘宝扭蛋机小程序系统的开发&#xff0c;旨在打造一个互动性强的购物平台&#xff0c;让用户在购物的同时&#xff0c;能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机&#xff0c;实现旋转、抽拉等动作&#xff0c;增…

Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storms…

毫米波雷达基础理论(3D+4D)

3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文&#xff1a; 一文入门汽车毫米波雷达基本原理 &#xff1a;https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…

TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?

在工业自动化持续演进的今天&#xff0c;通信网络的角色正变得愈发关键。 2025年6月6日&#xff0c;为期三天的华南国际工业博览会在深圳国际会展中心&#xff08;宝安&#xff09;圆满落幕。作为国内工业通信领域的技术型企业&#xff0c;光路科技&#xff08;Fiberroad&…

MySQL:分区的基本使用

目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区&#xff08;Partitioning&#xff09;是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分&#xff08;分区&#xff09;可以独立存储、管理和优化&#xff0c;…

HubSpot推出与ChatGPT的深度集成引发兴奋与担忧

上周三&#xff0c;HubSpot宣布已构建与ChatGPT的深度集成&#xff0c;这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋&#xff0c;但同时也存在一些关于数据安全的担忧。 许多网络声音声称&#xff0c;这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…

Rust 开发环境搭建

环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行&#xff1a; rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu ​ 2、Hello World fn main() { println…

Golang——7、包与接口详解

包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…

给网站添加live2d看板娘

给网站添加live2d看板娘 参考文献&#xff1a; stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下&#xff0c;文章也主…

手机平板能效生态设计指令EU 2023/1670标准解读

手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读&#xff0c;综合法规核心要求、最新修正及企业合规要点&#xff1a; 一、法规背景与目标 生效与强制时间 发布于2023年8月31日&#xff08;OJ公报&…

解析奥地利 XARION激光超声检测系统:无膜光学麦克风 + 无耦合剂的技术协同优势及多元应用

在工业制造领域&#xff0c;无损检测&#xff08;NDT)的精度与效率直接影响产品质量与生产安全。奥地利 XARION开发的激光超声精密检测系统&#xff0c;以非接触式光学麦克风技术为核心&#xff0c;打破传统检测瓶颈&#xff0c;为半导体、航空航天、汽车制造等行业提供了高灵敏…

从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障

关键领域软件测试的"安全密码"&#xff1a;Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力&#xff0c;从金融交易到交通管控&#xff0c;这些关乎国计民生的关键领域…

Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案

在大数据时代&#xff0c;海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构&#xff0c;在处理大规模数据抓取任务时展现出强大的能力。然而&#xff0c;随着业务规模的不断扩大和数据抓取需求的日益复杂&#xff0c;传统…

pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)

目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 &#xff08;1&#xff09;输入单引号 &#xff08;2&#xff09;万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…

论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing

Muffin 论文 现有方法 CRADLE 和 LEMON&#xff0c;依赖模型推理阶段输出进行差分测试&#xff0c;但在训练阶段是不可行的&#xff0c;因为训练阶段直到最后才有固定输出&#xff0c;中间过程是不断变化的。API 库覆盖低&#xff0c;因为各个 API 都是在各种具体场景下使用。…

【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制

目录 节点的功能承载层&#xff08;GATT/Adv&#xff09;局限性&#xff1a; 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能&#xff0c;如 Configuration …

关于easyexcel动态下拉选问题处理

前些日子突然碰到一个问题&#xff0c;说是客户的导入文件模版想支持部分导入内容的下拉选&#xff0c;于是我就找了easyexcel官网寻找解决方案&#xff0c;并没有找到合适的方案&#xff0c;没办法只能自己动手并分享出来&#xff0c;针对Java生成Excel下拉菜单时因选项过多导…

Ubuntu Cursor升级成v1.0

0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开&#xff0c;快捷键也不好用&#xff0c;当看到 Cursor 升级后&#xff0c;还是蛮高兴的 1. 下载 Cursor 下载地址&#xff1a;https://www.cursor.com/cn/downloads 点击下载 Linux (x64) &#xff0c;…

wpf在image控件上快速显示内存图像

wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像&#xff08;比如分辨率3000*3000的图像&#xff09;的办法&#xff0c;尤其是想把内存中的裸数据&#xff08;只有图像的数据&#xff0c;不包…

android RelativeLayout布局

<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:gravity&…