51基类与派生类的转换

简介: 51基类与派生类的转换

C++入门——60s从0到1

基类与派生类的转换

 

在C++中,基类和派生类之间可以进行类型转换。这种转换是通过动态类型转换(也称为多态)来实现的。

 

基类指针或引用与派生类对象的转换

 

如果一个基类指针或引用指向一个派生类对象,可以通过强制类型转换将其转换为派生类类型的指针或引用。

 

#include <iostream>
using namespace std;
 
class Base {
public:
    virtual void func() {
        cout << "Base::func()" << endl;
    }
};
 
class Derived : public Base {
public:
    void func() {
        cout << "Derived::func()" << endl;
    }
};
 
int main() {
    // 基类指针指向派生类对象
    Base* ptr = new Derived();
    ptr->func();  // 调用 Derived::func()
 
    // 将基类指针转换为派生类引用
    Derived& ref = *static_cast<Derived*>(ptr);
    ref.func();   // 调用 Derived::func()
 
    delete ptr;
    return 0;
}

在上面的例子中,我们创建了一个指向 `Derived` 对象的 `Base` 类型的指针 `ptr`。然后,我们通过强制类型转换将 `ptr` 从 `Base*` 转换为 `Derived*`,并将其赋值给 `Derived&` 类型的变量 `ref`。这样,我们就可以通过 `ref` 来调用 `Derived` 类型的成员函数 `func()`。

 

需要注意的是,如果基类没有虚函数,那么将无法通过基类指针或引用访问派生类的成员函数。因为编译器无法确定应该调用哪个函数,所以会引发编译错误。因此,在使用基类和派生类的转换时,通常需要将基类的虚函数声明为虚函数。

 

派生类对象与基类对象的转换

 

如果一个派生类对象可以被强制类型转换为一个基类类型的对象,那么这个派生类对象就可以被当作一个基类对象来处理。但是需要注意的是,这种强制类型转换可能会导致一些信息丢失。因为将一个派生类对象降级为一个基类对象后,它就失去了所有在派生类中新增的属性和行为。

#include <iostream>
using namespace std;
 
class Base {
public:
    virtual void func() {
        cout << "Base::func()" << endl;
    }
};
 
class Derived : public Base {
public:
    void func() {
        cout << "Derived::func()" << endl;
    }
};
 
int main() {
    // 将派生类对象降级为基类对象
    Base b = static_cast<Base&>(d);  // 强制类型转换为 Base&,而不是 Base*
    b.func();  // 调用 Base::func()
 
    return 0;
}

 

在上面的例子中,我们将一个 `Derived` 对象 `d` 通过强制类型转换降级为一个 `Base` 类型的对象 `b`。然后我们调用了 `b.func()`,由于 `Base` 的 `func()` 是虚函数,所以这里会调用 `Derived` 的 `func()` 函数。但是需要注意的是,此时我们已经将 `d` 的类型降为了 `Base`,所以它失去了所有在 `Derived` 中新增的属性和行为。

目录
相关文章
|
人工智能 API 决策智能
Modelscope结合α-UMi:基于Modelscope的多模型协作Agent
基于单个开源小模型的工具调用Agent,由于模型容量和预训练能力获取的限制,无法在推理和规划、工具调用、回复生成等任务上同时获得比肩大模型等性能。
|
Linux 关系型数据库 Oracle
rhel7安装oracle数据库软件,compat-libstdc++-33缺失
Missing or Ignored package compat-libstdc++-33-3.2.3
6730 0
|
7月前
|
机器学习/深度学习 供应链 数据可视化
增强现实,让物流与仓储更智能!
增强现实,让物流与仓储更智能!
202 4
|
开发工具 git 开发者
「Mac畅玩鸿蒙与硬件3」鸿蒙开发环境配置篇3 - DevEco Studio插件安装与配置
本篇将专注于如何在 DevEco Studio 中安装和配置必要的插件,以增强开发功能和提升效率。通过正确配置插件,开发流程能够得到简化,开发体验也会更加顺畅。
489 1
「Mac畅玩鸿蒙与硬件3」鸿蒙开发环境配置篇3 - DevEco Studio插件安装与配置
|
机器学习/深度学习 存储 监控
揭秘微调‘失忆’之谜:如何运用低秩适应与多任务学习等策略,快速破解灾难性遗忘难题?
【10月更文挑战第13天】本文介绍了几种有效解决微调灾难性遗忘问题的方法,包括低秩适应(LoRA)、持续学习和增量学习策略、记忆增强方法、多任务学习框架、正则化技术和适时停止训练。通过示例代码和具体策略,帮助读者优化微调过程,提高模型的稳定性和效能。
633 5
|
消息中间件 JSON 大数据
大数据-66 Kafka 高级特性 分区Partition 副本因子Replication Factor replicas动态修改 线上动态修改副本数
大数据-66 Kafka 高级特性 分区Partition 副本因子Replication Factor replicas动态修改 线上动态修改副本数
369 1
|
安全 定位技术 API
探讨如何在Flutter中集成支付、地图等第三方服务,以及集成过程中需要注意的问题和最佳实践
【6月更文挑战第11天】本文介绍了在Flutter中集成第三方服务,如支付和地图,以增强应用功能和用户体验。开发者可通过官方或社区插件集成服务,注意服务选择、API调用、错误处理和用户体验。支付集成涉及选择服务、获取API密钥、引入插件、调用API及处理结果。地图集成则包括选择地图服务、获取API密钥、初始化地图组件和添加交互功能。集成时要选择稳定插件、仔细阅读文档,处理错误,优化性能并遵循安全规范。随着Flutter生态发展,更多优质服务将可供选择。
348 2
|
存储 安全 Java
Java中数据加密与解密的最佳实践
Java中数据加密与解密的最佳实践
|
编解码 安全 算法
【蓝牙系列】蓝牙5.4到底更新了什么(1)--- PAwR
蓝牙5.4规范中引入了一种新的逻辑传输“Periodic Advertising with Responses(PAwR)”,它能够支持无连接的双向应用程序数据通信。在这种技术支持下,ESL设备不需要经常性的切换接收模式,因此可以大大延长电池寿命,同时,基于PAwR的数据传输模式,保证数据传输与监听设备的相关性,从而减少能量的浪费,实现ESL设备接收数据并响应至发送器的能力。
1632 0
|
存储 关系型数据库 MySQL
MySQL基础入门:数据库操作全攻略
MySQL基础入门:数据库操作全攻略
1064 0