C++笔记之基类指针动态地指向某一个子类情况列举

C++笔记之基类指针动态地指向某一个子类情况列举

code review!

文章目录

  • C++笔记之基类指针动态地指向某一个子类情况列举
    • 1.基本的多态示例
    • 2.基类中的成员函数可以设置为纯虚函数
    • 3.将基本示例修改为使用智能指针并在堆上实例化子类
    • 4.父类指针指向基类后,可以去调用只有子类才有的成员函数吗?
    • 5.子类和基类的构造函数之间的关系
    • 6.若子类和基类的构造函数不同情况一(没有用虚函数)
    • 7.若子类和基类的构造函数不同情况二(没有用虚函数)
    • 8.若子类和基类的构造函数不同情况三(修改情况二的代码为堆上实例化,使用虚函数)
    • 9.C++中的构造函数(constructor)不能被声明为虚函数。
    • 10.C++中基类指针动态地指向某一个子类(结合switch使用)情况一
    • 11.C++中基类指针动态地指向某一个子类(结合switch使用)情况二,使用智能指针
    • 12.C++中基类指针动态地指向某一个子类(结合switch使用)情况三,在switch前就在堆上实例化
    • 13.C++中基类指针动态地指向某一个子类(结合switch使用)情况三,在switch前就在堆上实例化,使用智能指针和std::move

1.基本的多态示例

在这里插入图片描述

代码

#include <iostream>class Base {
public:virtual void display() {std::cout << "This is the Base class." << std::endl;}
};class Derived1 : public Base {
public:void display() override {std::cout << "This is Derived1." << std::endl;}
};class Derived2 : public Base {
public:void display() override {std::cout << "This is Derived2." << std::endl;}
};int main() {Base* ptr;Derived1 derived1;Derived2 derived2;ptr = &derived1;ptr->display(); // 输出:This is Derived1.ptr = &derived2;ptr->display(); // 输出:This is Derived2.return 0;
}

2.基类中的成员函数可以设置为纯虚函数

在这里插入图片描述

3.将基本示例修改为使用智能指针并在堆上实例化子类

在这里插入图片描述

代码

#include <iostream>
#include <memory>class Base {
public:virtual void display() {std::cout << "This is the Base class." << std::endl;}virtual ~Base() {} // Virtual destructor to ensure proper cleanup
};class Derived1 : public Base {
public:void display() override {std::cout << "This is Derived1." << std::endl;}
};class Derived2 : public Base {
public:void display() override {std::cout << "This is Derived2." << std::endl;}
};int main() {std::unique_ptr<Base> ptr;ptr = std::make_unique<Derived1>();ptr->display(); // 输出:This is Derived1.ptr = std::make_unique<Derived2>();ptr->display(); // 输出:This is Derived2.return 0;
}

4.父类指针指向基类后,可以去调用只有子类才有的成员函数吗?

在这里插入图片描述

5.子类和基类的构造函数之间的关系

在这里插入图片描述

6.若子类和基类的构造函数不同情况一(没有用虚函数)

在这里插入图片描述

代码

#include <iostream>class Base {
private:int baseValue;public:Base(int value) : baseValue(value) {std::cout << "Base constructor with value: " << baseValue << std::endl;}void display() {std::cout << "Base value: " << baseValue << std::endl;}
};class Derived : public Base {
private:int derivedValue;public:// 子类构造函数调用基类构造函数,然后初始化子类成员Derived(int baseVal, int derivedVal) : Base(baseVal), derivedValue(derivedVal) {std::cout << "Derived constructor with values: " << baseVal << ", " << derivedVal << std::endl;}void display() {Base::display(); // 调用基类的 display 函数std::cout << "Derived value: " << derivedValue << std::endl;}
};int main() {Derived derived(10, 20);derived.display();return 0;
}

7.若子类和基类的构造函数不同情况二(没有用虚函数)

在这里插入图片描述

代码

#include <iostream>class Base {
private:int baseValue;public:Base() : baseValue(0) {std::cout << "Base default constructor" << std::endl;}void display() {std::cout << "Base value: " << baseValue << std::endl;}
};class Derived : public Base {
private:int derivedValue;public:// 子类构造函数有参数,调用基类默认构造函数,然后初始化子类成员Derived(int derivedVal) : Base(), derivedValue(derivedVal) {std::cout << "Derived constructor with value: " << derivedVal << std::endl;}void display() {Base::display(); // 调用基类的 display 函数std::cout << "Derived value: " << derivedValue << std::endl;}
};int main() {Derived derived(20);derived.display();return 0;
}

8.若子类和基类的构造函数不同情况三(修改情况二的代码为堆上实例化,使用虚函数)

在这里插入图片描述

运行
在这里插入图片描述

代码

#include <iostream>class Base {
private:int baseValue;public:Base() : baseValue(0) {std::cout << "Base default constructor" << std::endl;}virtual ~Base() {std::cout << "Base destructor" << std::endl;}virtual void display() {std::cout << "Base value: " << baseValue << std::endl;}
};class Derived : public Base {
private:int derivedValue;public:// 子类构造函数有参数,调用基类默认构造函数,然后初始化子类成员Derived(int derivedVal) : Base(), derivedValue(derivedVal) {std::cout << "Derived constructor with value: " << derivedVal << std::endl;}~Derived() {std::cout << "Derived destructor" << std::endl;}void display() {Base::display(); // 调用基类的 display 函数std::cout << "Derived value: " << derivedValue << std::endl;}
};int main() {Base* ptr = new Derived(20);ptr->display();delete ptr;return 0;
}

9.C++中的构造函数(constructor)不能被声明为虚函数。

10.C++中基类指针动态地指向某一个子类(结合switch使用)情况一

在这里插入图片描述

运行
在这里插入图片描述

代码

#include <iostream>class Base {
public:virtual void display() {std::cout << "This is the Base class." << std::endl;}
};class Derived1 : public Base {
public:void display() override {std::cout << "This is Derived1." << std::endl;}
};class Derived2 : public Base {
public:void display() override {std::cout << "This is Derived2." << std::endl;}
};int main() {int choice;Base* ptr = nullptr;std::cout << "Enter your choice (1 for Derived1, 2 for Derived2): ";std::cin >> choice;switch (choice) {case 1:ptr = new Derived1;break;case 2:ptr = new Derived2;break;default:std::cout << "Invalid choice." << std::endl;return 1;}if (ptr) {ptr->display();delete ptr;}return 0;
}

11.C++中基类指针动态地指向某一个子类(结合switch使用)情况二,使用智能指针

在这里插入图片描述

运行
在这里插入图片描述

代码

#include <iostream>
#include <memory> // 包含智能指针所需的头文件class Base {public:virtual void display() {std::cout << "This is the Base class." << std::endl;}
};class Derived1 : public Base {public:void display() override {std::cout << "This is Derived1." << std::endl;}
};class Derived2 : public Base {public:void display() override {std::cout << "This is Derived2." << std::endl;}
};int main() {int choice;std::cout << "Enter your choice (1 for Derived1, 2 for Derived2): ";std::cin >> choice;std::unique_ptr<Base> ptr; // 使用 std::unique_ptr 来替代原始指针switch (choice) {case 1:ptr = std::make_unique<Derived1>(); // 使用 std::make_unique 创建实例break;case 2:ptr = std::make_unique<Derived2>(); // 使用 std::make_unique 创建实例break;default:std::cout << "Invalid choice." << std::endl;return 1;}ptr->display();// 不再需要手动删除,unique_ptr 会在作用域结束时自动释放内存return 0;
}

12.C++中基类指针动态地指向某一个子类(结合switch使用)情况三,在switch前就在堆上实例化

在这里插入图片描述

代码

#include <iostream>class Base {
public:virtual void display() {std::cout << "This is the Base class." << std::endl;}
};class Derived1 : public Base {
public:void display() override {std::cout << "This is Derived1." << std::endl;}
};class Derived2 : public Base {
public:void display() override {std::cout << "This is Derived2." << std::endl;}
};int main() {Derived1* derived1 = new Derived1();Derived2* derived2 = new Derived2();int choice;std::cout << "Enter your choice (1 for Derived1, 2 for Derived2): ";std::cin >> choice;Base* ptr = nullptr;switch (choice) {case 1:ptr = derived1;break;case 2:ptr = derived2;break;default:std::cout << "Invalid choice." << std::endl;delete derived1;delete derived2;return 1;}ptr->display();delete derived1;delete derived2;return 0;
}

13.C++中基类指针动态地指向某一个子类(结合switch使用)情况三,在switch前就在堆上实例化,使用智能指针和std::move

在这里插入图片描述

运行
在这里插入图片描述

代码

#include <iostream>
#include <memory> // 包含智能指针所需的头文件class Base {public:virtual void display() {std::cout << "This is the Base class." << std::endl;}
};class Derived1 : public Base {public:void display() override {std::cout << "This is Derived1." << std::endl;}
};class Derived2 : public Base {public:void display() override {std::cout << "This is Derived2." << std::endl;}
};int main() {std::unique_ptr<Derived1> derived1 = std::make_unique<Derived1>();std::unique_ptr<Derived2> derived2 = std::make_unique<Derived2>();int choice;std::cout << "Enter your choice (1 for Derived1, 2 for Derived2): ";std::cin >> choice;std::unique_ptr<Base> ptr;switch (choice) {case 1:ptr = std::move(derived1); // 使用 std::move 进行所有权转移break;case 2:ptr = std::move(derived2); // 使用 std::move 进行所有权转移break;default:std::cout << "Invalid choice." << std::endl;return 1;}ptr->display();return 0; // 在作用域结束时,智能指针会自动释放内存
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Android Framework (十二) 】- 智能硬件设备开发

文章目录 前言智能硬件的定义与应用智能硬件产品开发流程智能硬件开发所涉及的技术体系概述关于主板选型主板CPU芯片的选择关于串口通信 总结 前言 针对我过往工作经历&#xff0c;曾在一家智能科技任职Android开发工程师&#xff0c;简单介绍下关于任职期间接触和开发过的一些…

幼儿园托幼机构管理系统 微信小程序

托幼机构管理系统微信小程序从功能、数据流程、可行性、运行环境进行需求分析。对托幼机构管理系统微信小程序的数据库、功能进行了详细设计&#xff0c;分析了主要界面设计和相关组件设计&#xff0c;托幼机构管理系统微信小程序的具体实现进行了介绍。从数据库中获取数据、向…

.netcore windows app启动webserver

创建controller: using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.Json.Serialization; using System.Threading.Tasks;namespace MyWorker.…

Linux 进程的地址空间

一、进程 进程&#xff1a;是一个正在运行的程序 PCB : 即是进程控制块&#xff0c;是进程存在的唯一标志。用来描述进程的属性信息&#xff0c;如进程的pid。 每一个进程都是通过fork复制而来的。 在执行fork之后&#xff0c;先将PCB复制一份给子进程&#xff0c;复制之前先…

美国大模型风向速报(一)为何重视提示工程?LangChain+向量数据库+开源大模型真香...

多家&#xff0c;且独家来自美国的信源同时向“亲爱的数据”表示&#xff0c; 提示工程&#xff08;Prompt Engineering&#xff09;在美国大模型领域备受重视。 读者都要聊&#xff0c; 那就干活。 &#xff08;一&#xff09;开源真香 现阶段&#xff0c;AI开源极客大展身手&…

CloudQuery实战 | 谁说没有一款一体化数据库操作管控云平台了?

文章目录 CloudQuery询盾的地址CloudQuery主页统一入口数据库归纳SQL编辑器权限管控审计中心数据保护数据变更 CloudQuery文档中心了解CloudQuery快速入门安装步骤社区版v2.1.0操作手册1数据查询更新日志 CloudQuery社区和活动 CloudQuery线上实战线上实战主页面展示及数据操作…

java实现人物关系抽取

java实现人物关系抽取 人物关系抽取是实体关系抽取的一种情况。实际上是两个过程&#xff1a;命名实体识别和关系抽取。 Java人物关系抽取是指从文本中提取出与Java相关的人物之间的关系。这个过程可以通过自然语言处理和文本分析的方法来实现。具体的步骤包括&#xff1a; 文本…

非常详细的 Ceph 介绍、原理、架构

1. Ceph架构简介及使用场景介绍 1.1 Ceph简介 Ceph是一个统一的分布式存储系统&#xff0c;设计初衷是提供较好的性能、可靠性和可扩展性。 Ceph项目最早起源于Sage就读博士期间的工作&#xff08;最早的成果于2004年发表&#xff09;&#xff0c;并随后贡献给开源社区。在经过…

(7)(7.6) 恢复任务回放

文章目录 前言 7.6.1 配置 7.6.2 工作原理 7.6.3 局限性 前言 本页介绍了什么是"任务继续时后退"功能以及如何使用该功能。 &#xff01;Note 从 4.1 版起&#xff0c;Plane、Copter 和 Rover 均可使用此功能。 在某些应用或运行区域&#xff0c;为了消除冲突&…

okhttp源码简单流程分析

拦截器详细解析可以看大佬简书 "https://www.jianshu.com/p/6fac73f7570f"和 “https://www.jianshu.com/p/3c740829475c” okhttp请求流程 1&#xff1a;OkHttpClient okHttpClient new OkHttpClient.Builder() 构建一个okhttpClient对象&#xff0c;传入你想传入的…

2023国赛数学建模D题思路模型代码 高教社杯

本次比赛我们将会全程更新思路模型及代码&#xff0c;大家查看文末名片获取 之前国赛相关的资料和助攻可以查看 2022数学建模国赛C题思路分析_2022国赛c题matlab_UST数模社_的博客-CSDN博客 2022国赛数学建模A题B题C题D题资料思路汇总 高教社杯_2022国赛c题matlab_UST数模社…

【IEEE会议】第二届IEEE云计算、大数据应用与软件工程国际学术会议 (CBASE2023)

第二届IEEE云计算、大数据应用与软件工程国际学术会议 (CBASE2023&#xff09; 随着大数据时代的到来&#xff0c;对数据获取的随时性和对计算的需求也在逐渐增长。为推动大数据时代的云计算与软件工程的发展&#xff0c;促进该领域学术交流&#xff0c;在CBASE 2022成功举办的…

人工智能在网络安全中的应用: 分析人工智能、机器学习和深度学习等技术在预测、检测和应对网络攻击中的作用

第一章&#xff1a;引言 随着信息技术的迅猛发展&#xff0c;网络安全已成为当今社会不容忽视的重要议题。网络攻击手法日益复杂&#xff0c;传统的防御方法已经不再足够。在这一背景下&#xff0c;人工智能&#xff08;AI&#xff09;技术正逐渐崭露头角&#xff0c;为网络安…

循环神经网络RNN完全解析:从基础理论到PyTorch实战

目录 一、循环神经网络全解1.1 什么是循环神经网络网络结构工作原理数学模型RNN的优缺点总结 1.2 循环神经网络的工作原理RNN的时间展开数学表述信息流动实现示例梯度问题&#xff1a;梯度消失和爆炸总结 1.3 循环神经网络的应用场景文本分析与生成1.3.1 自然语言处理1.3.2 机器…

unity打造路径编辑与导航系统

Unity是一款非常流行的游戏引擎&#xff0c;它提供了丰富的工具和API&#xff0c;方便开发者快速创建游戏。其中&#xff0c;路径编辑与导航系统是游戏开发中非常重要的一部分&#xff0c;可以帮助玩家更好地探索游戏世界&#xff0c;提升游戏体验。本文将详细介绍如何在Unity中…

C#与西门子PLC1500的ModbusTcp服务器通信2--ModbusTcp协议

Modbus TCP是近年来越来越流行的工业控制系统通信协议之一&#xff0c;与其他通信协议相比&#xff0c;Modbus TCP通信速度快、可靠性高、兼容性强、适用于模拟或数字量信号的传输&#xff0c;阅读本文前你必须比较熟悉Modbus协议&#xff0c;了解tcp网络。 一、什么是Modbus …

自动驾驶合成数据科普一:不做真实数据的“颠覆者”,做“杠杆”

前言&#xff1a; 在7月底的一篇文章中&#xff0c;九章智驾提到&#xff0c;数据闭环能力是自动驾驶下半场的“入场券”&#xff0c;这一观点在行业内引起了广泛共鸣。 在数据闭环体系中&#xff0c;仿真技术无疑是非常关键的一环。仿真的起点是数据&#xff0c;而数据又分为真…

Linux网络编程:网络基础

文章目录&#xff1a; 一&#xff1a;协议 二&#xff1a;网络应用设计模式_BS模式和CS模式 三&#xff1a;网络分层模型&#xff08;OSI七层 TCP/IP四层&#xff09; 四&#xff1a;通信过程 五&#xff1a;协议格式 1.数据包封装 2.以太网帧格式和ARP数据报格式 …

【HarmonyOS】【DevEco Studio】ohpm安装失败该如何解决?

【关键词】 HarmonyOS、DevEco Studio、ohpm安装失败 【问题背景及解决方案】 最近遇到很多DevEco Studio安装ohpm失败的问题&#xff0c;下面给大家介绍几种出现的问题以及解决方案&#xff1a; 1、ohpm not set up&#xff0c;报错截图如下&#xff1a; ​ 解决方案&…

基于YOLOv8模型和PCB电子线路板缺陷目标检测系统(PyTorch+Pyside6+YOLOv8模型)

摘要&#xff1a;基于YOLOv8模型PCB电子线路板缺陷目标检测系统可用于日常生活中检测与定位PCB线路板瑕疵&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的目标检测&#xff0c;另外本系统还支持图片、视频等格式的结果可视化与结果导出。本系统采用YOLOv8目标检…