当前位置: 首页 > news >正文

C++基类指针或引用指向或引用派生类对象(实现动态多态四种手段)父类指针访问子类成员变量(需要dynamic_cast)

文章目录

    • 背景
    • 多态示例:父类指针指向子类对象
    • 父类指针指向子类对象,如何通过父类指针访问到子类特定的成员变量
    • 实现动态多态的四种手段:基类的指针或引用指向或引用一个派生类对象(new或不new)

背景

比如有父类Animal和子类Cat,用new创建对象有以下四种方式:

Animal* p = new Cat();
Animal* pp = new Animal();
Cat* q = new Cat();
Cat* qq = new Animal();

其中第四种是不合法的。

第二种和第三种都好理解,但是第一种,用父类指针指向了子类对象,这种是干嘛用的的🧐

这是用来实现多态的

多态示例:父类指针指向子类对象

使用父类指针指向子类对象时,可以实现多态性,即在运行时根据对象的实际类型来调用相应的函数。这样可以方便地实现代码的扩展和维护,同时也可以提高代码的可读性和可维护性。

下面是一个简单的示例代码,演示了使用父类指针指向子类对象的好处:

#include <iostream>
using namespace std;class Animal
{
public:virtual void speak(){cout << "Animal speaks" << endl;}string name;
};class Cat : public Animal
{
public:void speak(){cout << "Cat speaks" << endl;}string name;
};class Dog : public Animal
{
public:void speak(){cout << "Dog speaks" << endl;}
};int main()
{Animal *p1 = new Cat();Animal *p2 = new Dog();p1->speak(); // 输出 Cat speaksp2->speak(); // 输出 Dog speaksdelete p1;delete p2;return 0;
}

在上面的代码中,Animal是一个基类,Cat和Dog是Animal的子类。在main函数中,我们使用Animal指针p1和p2分别指向Cat对象和Dog对象。由于speak函数是虚函数,因此在运行时会根据对象的实际类型来调用相应的函数。因此,p1->speak()会调用Cat类中的speak函数,输出"Cat speaks",p2->speak()会调用Dog类中的speak函数,输出"Dog speaks"。

如果我们不使用父类指针指向子类对象,而是直接使用Cat和Dog对象,那么我们就需要分别调用它们的speak函数,这样会导致代码的重复和冗余,不利于代码的扩展和维护。

父类指针指向子类对象,如何通过父类指针访问到子类特定的成员变量

当使用父类指针指向子类对象时,无法直接访问子类中特定的成员变量。但是,可以通过将父类指针转换为子类指针或引用来访问子类中特定的成员变量。

在C++中,可以使用dynamic_cast运算符将父类指针或引用转换为子类指针或引用,从而访问子类中特定的成员变量。需要注意的是,dynamic_cast运算符只能用于含有虚函数的类类型之间的转换,而且转换时会进行类型检查,如果转换失败会返回空指针或引用。

下面是一个简单的示例代码,演示了如何使用dynamic_cast运算符访问子类中特定的成员变量:

#include <iostream>
using namespace std;class Animal
{
public:virtual void speak(){cout << "Animal speaks" << endl;}
};class Cat : public Animal
{
public:string name;void speak(){cout << "Cat speaks" << endl;}
};int main()
{Animal *p = new Cat();p->speak(); // 输出 Cat speaksCat *q = dynamic_cast<Cat *>(p);if (q != nullptr){q->name = "Tom";cout << q->name << endl; // 输出 Tom}delete p;return 0;
}

在上面的代码中,Animal类中没有定义name成员变量,而Cat类中定义了name成员变量。在main函数中,我们使用Animal指针p指向Cat对象,然后使用dynamic_cast运算符将p转换为Cat指针q,从而访问Cat类中的name成员变量。需要注意的是,在转换时需要进行类型检查,如果转换失败会返回空指针。

参考文章:C++四种cast转换(const_cast、static_cast、dynamic_cast、reinpreter_cast)类型转换运算符

实现动态多态的四种手段:基类的指针或引用指向或引用一个派生类对象(new或不new)

可以定义一个基类的指针或引用,然后将其指向或引用一个派生类的对象。这样,通过基类的指针或引用调用虚函数时,会根据实际指向的对象类型来动态调用相应的函数,从而实现多态。

下面是一个使用指针实现多态的示例代码:

#include <iostream>
using namespace std;// 重写示例
class Base
{
public:virtual void func(){cout << "Base::func()" << endl;}
};class Derived : public Base
{
public:virtual void func(){cout << "Derived::func()" << endl;}
};int main()
{// 方法1:new,父类指针指向子类对象Base *p = new Derived();p->func(); // 输出 Derived::func()delete p;cout << "----" << endl;// 或者// 方法2:不new,父类指针指向子类对象Derived dd;Base *pp = &dd;pp->func(); // 输出 Derived::func()cout << "----" << endl;// 或者// 方法3:不new,父类引用引用子类对象Derived ddd;Base &ppp = ddd;ppp.func(); // 输出 Derived::func()cout << "----" << endl;// 或者// 方法4:new,父类引用引用子类对象Base &pppp = *(new Derived());pppp.func(); // 输出 Derived::func()delete &pppp;return 0;
}

在上面的代码中,定义了一个基类的指针或引用,然后将其指向一个派生类对象。通过基类的指针或引用调用虚函数时,会根据实际指向的对象类型来动态调用相应的函数,从而输出派生类中的func()函数的内容。

相关文章:

C++基类指针或引用指向或引用派生类对象(实现动态多态四种手段)父类指针访问子类成员变量(需要dynamic_cast)

文章目录 背景多态示例&#xff1a;父类指针指向子类对象父类指针指向子类对象&#xff0c;如何通过父类指针访问到子类特定的成员变量实现动态多态的四种手段&#xff1a;基类的指针或引用指向或引用一个派生类对象&#xff08;new或不new&#xff09; 背景 比如有父类Animal…...

WTM框架运行报错0308010C:digital envelope routines::unsupported

WTM框架运行报错0308010C:digital envelope routines::unsupported 错误描述报错原因解决方式 错误描述 我所使用WTM搭建的程序是选择的.net5.0Vue前后端分离的方式&#xff0c;项目结构选择的是“各层分离的多个项目”&#xff1b;本人并非初次使用WTM平台框架搭建项目&#…...

(二)CSharp-索引器

1、索引器定义 什么是索引器 索引器&#xff08;indexer&#xff09;是这样一种成员&#xff1a;它使对象能够用与数组相同的方式&#xff08;即使用下标&#xff09;进行索引 索引器的声明参见 C# 语言定义文档注意&#xff1a;没有静态索引器 索引器是一组 get 和 set 访问…...

配合AI刷leetcode 实现1170

题目如下&#xff1a; 1170. 比较字符串最小字母出现频次 难度中等 75 定义一个函数 f(s)&#xff0c;统计 s 中&#xff08;按字典序比较&#xff09;最小字母的出现频次 &#xff0c;其中 s 是一个非空字符串。 例如&#xff0c;若 s "dcce"&#xff0c;那么…...

English Learning - L3 作业打卡 Lesson5 Day36 2023.6.9 周五

English Learning - L3 作业打卡 Lesson5 Day36 2023.6.9 周五 引言&#x1f349;句1: So next time you are on a train, look around and see what other people are reading, but dont jump to any conclusions.成分划分弱读连读爆破语调 &#x1f349;句2: You will probab…...

前端框架笔记

Vue.js的安装 安装Vue.js有两种方法&#xff1a; &#xff08;1&#xff09;类似于Bootstrap或jQuery&#xff0c;直接通过HTML文件中的标签引用。为了方便开发者使用&#xff0c;Vue.js提供了相关的CDN&#xff0c;通过如下代码可以引用最新版本的Vue.js&#xff1a; <sc…...

详细设计文档

1. 引言 1.1 目的 1.2 范围 1.3 定义、缩略语和缩写 1.4 参考文献 1.5 概述 2. 系统架构设计 2.1 总体架构 2.2 模块划分 2.3 数据流程设计 2.4 接口设计 3. 模块详细设计 3.1 登录模块详细设计 3.1.1 类设计 3.1.2 方法设计 3.1.3 数据库表设计 3.1.4 界面设计 3.2 文章管理模…...

Java011——Java数据类型转换(基本数据类型)

回顾&#xff1a;Java八大基本数据类型 大类 类型名称 关键字 占用内存 取值范围 --------------------------------------------------------------------------------------------|字节型 byte 1 字节 -128~127 整型 |短整型 short 2 字节 -32768~32…...

mybatis-plus用法(二)

(5条消息) mybatis-plus用法&#xff08;一&#xff09;_渣娃工程师的博客-CSDN博客 AR模式 ActiveRecord模式&#xff0c;通过操作实体对象&#xff0c;直接操作数据库表。与ORM有点类似。 示例如下 让实体类User继承自Model package com.example.mp.po; import com.bao…...

SQL笔记-存储过程+循环

存储过程循环使用方法 Oracle Oracle中存储过程的循环使用方法如下&#xff1a; DECLAREi NUMBER; BEGINi : 1;WHILE i < 10 LOOPDBMS_OUTPUT.PUT_LINE(i || i);i : i 1;END LOOP; END;其中&#xff0c;DECLARE用于声明变量&#xff0c;BEGIN和END用于标识存储过程的开始…...

HNU-操作系统OS-作业1(4-9章)

这份文件是OS_homework_1 by计科2102 wolf 202108010XXX 文档设置了目录,可以通过目录快速跳转至答案部分。 第四章 4.1用以下标志运行程序:./process-run.py -l 5:100,5:100。CPU 利用率(CPU 使用时间的百分比)应该是多少?为什么你知道这一点?利用 -c 标记查看你…...

springboot 精华

一、基础 官方文档地址&#xff1a;Spring Boot 注&#xff1a;以下部分例子 有些用到 .properties 方式&#xff0c;有些用 .yml方式&#xff0c;两者可自行学习&#xff0c;这里部分是为了省空间而写 .properties 方式。 1、泛谈 &#xff08;1&#xff09;优势 快速构建…...

我用ChatGPT写2023高考语文作文(三):新课标I卷

2023年 新课标I卷 适用地区&#xff1a;山东、福建、湖北、江苏、广东、湖南、河北、浙江 好的故事&#xff0c;可以帮我们更好地表达和沟通&#xff0c;可以触动心灵、启迪智慧&#xff1b;好的故事&#xff0c;可以改变一个人的命运&#xff0c;可以展现一个民族的形象……故…...

HTML 标签的学习

1.HTML 的结构 前端三剑客: HTML CSS JS,本章我们学习的是HTML HTML > 超文本标记语言 HTML代码是由"标签"构成的. 形如 <body>hello</body>标签名 (body) 放到 < > 中大部分标签成对出现. 为开始标签, 为结束标签.少数标签只有开始标签…...

计算耗时为微秒的方法(包含:时/分/秒/毫秒/微秒/纳秒)

计算耗时为微秒的方法1 #include<stdio.h> #include <windows.h> int main() {int a[10002];int i 0;double run_time;_LARGE_INTEGER time_start; //开始时间_LARGE_INTEGER time_over; //结束时间double dqFreq; //计时器频率LARGE_INTEGER f; //计时器频率Qu…...

通过 Python 封装关键词搜索阿里巴巴商品api接口

以下是使用 Python 封装关键词搜索阿里巴巴商品列表数据的步骤&#xff1a; 使用 requests 库向阿里巴巴搜索接口发送 HTTP 请求&#xff0c;可以使用 GET 或 POST 方法&#xff0c;请求参数中应包含搜索关键词、每页展示数量、当前页码等信息。 解析返回的 response 中的 HTM…...

分布式光伏消纳的微电网群共享储能配置策略研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

C语言写网络爬虫总体思路

使用C语言编写爬虫可以实现网络数据的快速获取和处理&#xff0c;适用于需要高效处理海量数据的场景。与其他编程语言相比&#xff0c;C语言具有较高的性能和灵活性&#xff0c;可以进行底层操作和内存管理&#xff0c;适合处理较复杂的网络请求和数据处理任务。 但是&#xf…...

机器学习实战六步法之训练模型、优化模型、部署模型(七)

要落地一个机器学习的项目&#xff0c;是有章可循的&#xff0c;通过这六个步骤&#xff0c;小白也能搞定机器学习。 看我闪电六连鞭&#xff01;&#x1f923; 训练模型 当确定好机器学习算法之后&#xff0c;就可以通过训练数据集中的特征和标签&#xff0c;根据样本数据的…...

《C++高级编程》读书笔记(七:内存管理)

1、参考引用 C高级编程&#xff08;第4版&#xff0c;C17标准&#xff09;马克葛瑞格尔 2、建议先看《21天学通C》 这本书入门&#xff0c;笔记链接如下 21天学通C读书笔记&#xff08;文章链接汇总&#xff09; 1. 使用动态内存 1.1 如何描绘内存 在本书中&#xff0c;内存单…...

从CANdb++到Matlab:手把手教你读懂DBC文件里的信号映射与物理值转换

从CANdb到Matlab&#xff1a;手把手教你读懂DBC文件里的信号映射与物理值转换 在汽车电子和嵌入式系统开发中&#xff0c;DBC文件作为CAN总线通信的"字典"&#xff0c;承载着整车网络通信的核心协议。对于刚接触汽车网络通信的工程师来说&#xff0c;面对DBC文件中密…...

终极Windows安卓应用安装指南:告别模拟器,拥抱轻量级体验

终极Windows安卓应用安装指南&#xff1a;告别模拟器&#xff0c;拥抱轻量级体验 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 你是否厌倦了笨重的安卓模拟器&#x…...

基于MCP协议构建AI知识库:Alexandria项目部署与核心工作流解析

1. 项目概述&#xff1a;让AI拥有自己的“亚历山大图书馆”如果你和我一样&#xff0c;长期与各种AI助手&#xff08;比如Claude、Cursor、Codex&#xff09;打交道&#xff0c;肯定会遇到一个头疼的问题&#xff1a;知识无法沉淀。今天你花半小时教会AI助手某个项目的架构细节…...

从磁路对称性到电感差异:深度解析永磁同步电机凸极与隐极的本质

1. 永磁同步电机的两种面孔&#xff1a;凸极与隐极 第一次拆解永磁同步电机时&#xff0c;我被转子铁芯上那些凹凸有致的磁极结构吸引了——有的像连绵的山丘&#xff08;凸极&#xff09;&#xff0c;有的则平整得像镜面&#xff08;隐极&#xff09;。这两种结构看似只是外观…...

手把手教你用GD32F303定时器PWM驱动LED,从寄存器配置到CubeMX生成代码

GD32F303定时器PWM开发全攻略&#xff1a;寄存器配置与图形化工具实战对比 在嵌入式开发领域&#xff0c;PWM&#xff08;脉冲宽度调制&#xff09;技术如同一位无声的指挥家&#xff0c;精准控制着LED亮度、电机转速等关键参数。对于GD32F303这款高性能ARM Cortex-M4内核微控制…...

基于SAP CAP与RAG技术构建企业级智能问答系统实战指南

1. 项目概述&#xff1a;当企业级应用遇上生成式AI最近在做一个企业级应用的智能问答功能&#xff0c;客户要求能基于他们内部的海量文档&#xff08;PDF、Word、Excel&#xff09;进行精准回答&#xff0c;而不是让大模型“自由发挥”。这让我想起了SAP官方在GitHub上开源的那…...

从一次失败的模型交付说起:我是如何用random_state拯救项目复现的

从一次失败的模型交付说起&#xff1a;我是如何用random_state拯救项目复现的 那是一个周五的下午&#xff0c;团队群里的消息突然炸开了锅。"你确定这是同一个模型&#xff1f;测试集AUC从0.92跌到0.68了&#xff01;"看着同事发来的对比截图&#xff0c;我的后背瞬…...

为什么92%的团队用错Gemini做Slides?——基于17家SaaS公司实测数据的生成效率断层分析

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;Gemini生成Slides的底层机制与能力边界 Gemini 生成幻灯片&#xff08;Slides&#xff09;并非简单地将文本转为 PPT 页面&#xff0c;而是依托多模态大模型对语义结构、视觉层级与演示逻辑的联合建模。…...

Midjourney生成图落地PS的7大断层痛点:从提示词对齐、分辨率陷阱到图层级精修,一文打通AI与专业图像处理全链路

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;Midjourney与Photoshop整合方案的底层逻辑与工作流重构 Midjourney 生成的图像虽具高美学质量&#xff0c;但缺乏图层控制、非破坏性编辑及像素级精度&#xff0c;而 Photoshop 正是弥补这一缺口的核心…...

功能开关与远程配置:现代Web应用安全发布与动态控制实践

1. 项目概述&#xff1a;从“快乐工具包”到现代应用配置管理 如果你是一名前端或全栈开发者&#xff0c;最近在关注状态管理或应用配置&#xff0c;可能已经听说过 happykit/flags 这个名字。乍一看&#xff0c;它像是一个关于“旗帜”或“开关”的库&#xff0c;但它的核心…...