C++父类子类指针与多态的一些问题

Type-C快充移动电源芯片避坑指南:IP5356配置全流程(支持PD3.0) 本文详细解析了英集芯IP5356芯片在Type-C快充移动电源中的应用,提供了从芯片选型、原理图设计、PCB布局到PD协议调试的全流程实战指南。文章重点剖析了如何避免散热、EMI及协议握手等常见设计陷阱,并分享了量产前的关键测试验证方法,旨在帮助硬件开发者高效打造稳定可靠的快充产品。 阅读详情

上篇文章简要讲了多态场景下的一个坑,今天对父类指针和子类指针分别指向一个子类对象的访问权限以及调用析构函数问题。

class A
{
 public:
     virtual void func(int val = 1){ std::cout<<"A->"<< val <<std::endl;}
     virtual void test(){ func();}
 };
 
 class B : public A
 {
 public:
     void func(int val = 0){ std::cout<<"B->"<< val <<std::endl; }
 };
 
 int main(int argc ,char* argv[])
 {
    B*p1 = new B;
    A*p2 = new B;
    p1->test();
    p2->test();
     return 0;
 }

这里不管是p1还是p2调用test()函数,最终结果都是B->1,但是运行机制不一样。先分析p1->test(),p1->test() 是通过派生类指针调用,直接访问 A::test(),又因为B重写了func()函数,会调用 B::func()(动态绑定),不过默认参数的值还是由 A::func() 决定(静态绑定),主要原因还是因为A的func()是虚函数; p2->test()的分析差别在于p2是父类指针,加上虚函数满足了多态的条件,而p1是派生类指针,不满足多态。

是否可以理解成 p1 和 p2 都指向一个 B 类对象,可以访问 B 类的全部内容?
p1 和 p2 都指向一个 B 类对象,这是正确的,所以在有虚函数func()时才能都调用B的func()。
但是p1(B* 类型):可以访问 B 类的全部内容(包括从 A 继承的部分和 B 自己定义的部分);而p2(A* 类型):只能访问 A 类的成员和 B 类重写的虚函数,不能直接访问 B 类的特有成员。

对代码进行修改,说明虚函数对析构的影响。

class A
{
 public:
     virtual void func(int val = 1){ std::cout<<"A->"<< val <<std::endl;}
     virtual void test(){ func();}
     ~A()
     {
     	cout<<"~A()"<<endl;
     }
 };
 
 class B : public A
 {
 public:
     void func(int val = 0){ std::cout<<"B->"<< val <<std::endl; }
      ~B()
     {
     	delete arr;
     	cout<<"~B()"<<endl;
     }
 private:
 	int* arr=new int[10];   
 };
 
 int main(int argc ,char* argv[])
 {
    B*p1 = new B;
    A*p2 = new B;
   // p1->test();
   // p2->test();
    delete p1;
    delete p2;
     return 0;
 }

对于delete p1,显然是先调用派生类析构函数再调用基类析构函数;但是对于delete p2,由于p2是A*,只能访问到派生类B的基类部分,所以只会调用~A(),没有调用B的析构函数,且~B() 存在资源释放,此时就会造成内存泄漏。当给~A() 前加上virtual时,无论派生类B的析构函数是否加关键字,都与基类的析构函数构成重写,虽然基类和派生类析构函数名不同看起来不符合重写的规则,实际上是编译器对析构函数名称做了特殊处理,编译后析构函数的名称统一为destructor,此时就不存在资源泄漏问题。
////简单总结就是
如果基类的析构函数不是虚函数,通过基类指针删除派生类对象时,会导致派生类的资源泄漏。将基类的析构函数声明为虚函数可以解决这个问题。
析构函数的重写:只要基类的析构函数是虚函数,派生类的析构函数就会自动成为虚函数(即使没有显式声明 virtual),不仅是析构函数,其他只要是基类函数有virtual,那么派生类的virtual可加可不加。

【系列05】端侧AI:构建与部署高效的本地化AI模型 第4章:模型量化(Quantization) 量化的基本思想是减少模型中用于表示参数和激活值的比特数。在模型训练时,参数通常使用32位浮点数(FP32)进行存储,这提供了高精度,但也消耗大量的内存和计算资源。量化则将这些32位浮点数转换成低比特数表示,通常是8位整数(INT8)。量化的原理可以概括为:对浮点数范围进行校准,并将其映射到更小的整数范围内。例如,将一个FP32的权重(如-1.5到1.5)映射到INT8的范围(-128到127)。在推理过程中,模型将使用这些低精度的整数进行计算,从而大大减少了所需的计算量。量化带来的主要收益减少模型大小。 阅读详情

相关推荐

银河麒麟V10安装docker

最近在做的一个信创项目使用的操作系统是银河麒麟高级服务器V10,在安装docker时,会遇到下面的错误。 nothing provides fuse-overlayfs >= 0.7 needed by docker-ce-rootless-extras-20.10.0-3.el7.x86_64 经过分析,以下依赖包是centos系统中的包,所以需要给kylinos创建一个合适的centos源。经过实验,Kylin Linux Advanced Server V1

m0_38004228的博客 4908

揭秘C++多态——父类指针如何正确调用函数?

你真的理解父类指针是如何调用函数的吗? 在C++的世界里,多态(Polymorphism)是面向对象编程的三大支柱之一。我们常常写下这样的代码: Base* ptr = new Derived(); ptr->virtualFunction(); 看似简单的一行调用,背后却隐藏着 this 指针、虚函数表(vtable)、动态绑定等精巧的机制。为什么父类指针能调用子类的实现?它又是如何“找到”正确函数的?this 指针在这个过程中扮演了什么角色?

大四在找工作,如果公司有需要的可以联系我13086825462@163.com 1359

在 Linux 虚拟机中手动安装 VMware Tools

对于 Linux 虚拟机,您可以从命令行手动安装 VMware Tools。对于 Linux 的较高发行版,请使用集成的 open-vm-tools 版本。 前提条件 有关 open-vm-tools 的操作系统兼容性的详细信息,请参见《VMware 兼容性指南》,网址为VMware Compatibility Guide - System Search。 开启虚拟机。 确认客户机操作系统正在运行。 因为 VMware Tools 安装程序是使用 Perl 编写的,请确认已在客户机操作系统中安..

m0_62526815的博客 1755

C++ 基类指针和派生类指针之间的转换

  函数重载、函数隐藏、函数覆盖 函数重载只会发生在同作用域中(或同一个类中),函数名称相同,但参数类型或参数个数不同。 函数重载不能通过函数的返回类型来区分,因为在函数返回之前我们并不知道函数的返回类型。 函数隐藏和函数覆盖只会发生在基类和派生类之间。 函数隐藏是指派生类中函数与基类中的函数同名,但是这个函数在基类中并没有被定义为虚函数,这种情况就是函数的隐藏。 所谓隐藏是指使用常规的调...

牧野的博客 2万+

Tesseract in Java - Intellij IDEA对Tess4J的配置和使用

最近要弄OCR,搜到这个,官网全英文,很烦,看看有没有中文的博客介绍,擦,一个比一个奇葩,还是自己按照官方的来吧,外网慢的很,传到csdn给大家下载。中文训练库下载地址: http://download.youkuaiyun.com/detail/d_dmelon/9916532Tess4J3.4下载地址: http://download.youkuaiyun.com/detail/d_dmelon/9916519安装

Lewis的博客 1万+

Qt图形视图框架实战:QGraphicsScene、QGraphicsView与QGraphicsItem的深度应用

本文深入解析Qt图形视图框架的核心组件QGraphicsScene、QGraphicsView与QGraphicsItem的实战应用。通过“舞台、镜头与演员”的比喻,清晰阐述了三者的协作关系,并详细介绍了场景管理、多视图同步、交互增强、自定义图形项绘制与性能优化等高级技巧,帮助开发者高效构建复杂的交互式图形界面。

weixin_29251337的博客 263

c++基类与继承类指针转换问题

1、如果你以一个"基类之指针"指向一个"派生类之对象",那么经由该指针你只能调用该基类所定义的函数 2、如果你以一个“派生类之指针”指向一个“基类之对象”,你必须先做明显的转型操作(explicit cast),这种作法很危险,不符合真实生活经验,在设计上也许会带给程序员困惑; 3、如果积累和派生类都定义了“相同名称之函数”,那么通过对象指针调用成员函数时,到底调用了那个函数,必须视该指针的原

extremevirus的专栏 1245

centos7搭建LNMP环境-编译安装&yum安装-超详细

文章目录1. 首先了解编译安装和yum安装的区别。2. yum安装准备工作---切换阿里云yum源3. 编译安装lnmp4.yum安装lnmp5. lnmp一键安装6. 一些报错7. 笔记8. 参考文章 1. 首先了解编译安装和yum安装的区别。 windows下安装centos虚拟机,之前写过。传送门~~ 编译安装: 可以按需安装,想安在哪个目录下就安在哪个目录下。 可以设定参数 可安装自己想要的版本 yum安装: 安装的方便快捷 不需要考虑包的依赖 可以直接使用service nginx st

最美不过下雨天 9349

C++ 多态问题:为什么不直接用子类引用子类,而是用父类指针指向子类

刚开始的时候对于这个问题我一直搞不明白,总觉得这是多此一举,后来上网查资料看到了一些人的解释明白了为什么要这样,用一个例子来解释应该最好理解了: 你写了一个飞机游戏,画面里出现什么类型飞机是随机决定的,你的代码里也就不可能用一个具体飞机类型来操作。 所以,往往是随机生成各种类型飞机,他们有共同的父类,你的代码就可以用父类指针来控制行为。比如中弹后的能量损失多少之类,每种飞机可能不同。 参考

marsggbo的博客 4526

保姆级教程:用Java和HslCommunication库搞定三菱PLC数据读写(附完整代码)

本文提供了一份详细的Java与三菱PLC通信教程,通过HslCommunication库实现高效数据读写。内容涵盖环境配置、通信模式选择、数据类型操作、异常处理及性能优化,并附有完整代码示例,帮助开发者快速掌握工业自动化中的PLC数据交互技术。

weixin_28731223的博客 227

动力学约束下的运动规划算法——Kinodynamic RRT*算法

动力学约束下的运动规划算法——Kinodynamic RRT*算法

慕羽★的博客 6749

C++-类-多态2:向上类型转换及问题【父类引用或指针可以指向子类对象,通过父类指针或引用来操作子类对象】

对于一种编译语言,编译器并不知道实际的对象类型(编译器并不知道Animal类型的指针或引用指向的实际的对象类型)。这个时候由于DoBussiness的参数类型是Animal&,编译器确定了应该调用的speak是Animal::speak的,而不是真正传入的对象Dog::speak。C++动态多态性是通过虚函数来实现的,虚函数允许子类(派生类)重新定义父类(基类)成员函数,而子类(派生类)重新定义父类(基类)虚函数的做法称为覆盖(override),或者称为重写。是根据指向对象的指针或引用的类型。

u013250861的博客 779

学Simulink——基于AI融合与智能调度的场实例:联邦学习支持的多卫星协同通信建模

本文介绍了一种基于联邦学习的多卫星协同通信Simulink建模方法。系统采用"星-星协同+星-地协调"架构,每颗卫星本地训练LSTM链路预测模型,地面中心通过FedAvg算法聚合模型参数。建模过程包括卫星通信模型构建、联邦学习机制设计、协同决策系统开发等步骤,支持隐私保护、高效协同和智能决策。仿真结果表明,该方法在预测准确率(89%)、吞吐量(56.7Mbps)等方面优于独立训练模式,接近集中式训练性能。该方案为大规模卫星星座的智能协同提供了仿真验证平台,未来可拓展去中心化联邦学习、异构

xiaoheshang_123的博客 209

一篇文章讲通:①C++里面的父类指针指向子类对象[与C++多态的知识点有关] 与 ②java里面的父类引用(或者说父类变量)指向子类对象[与java多态的知识点有关][在java中,这个简称:上转型]

一篇文章讲通: ①C++里面的父类指针指向子类对象[与C++多态的知识点有关] 与 ②java里面的父类引用(或者说父类变量)指向子类对象[与java多态的知识点有关] [在java中,这个简称:上转型]

敖丙007的博客 2016

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

数学建模模型总结

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

你还不进来看看C++类与对象【7】 —— 动态多态底层原理剖析&&(纯)虚析构解决父类指针不能释放子类属性问题嘛

一篇文章带你了解C++中的多态 多态满足条件有继承关系子类重写父类中的虚函数多态使用条件父类指针或引用指向子类对象重写:函数返回值类型 函数名 参数列表 完全一致称为重写C++开发提倡利用多态设计程序架构,因为多态优点很多。子类中有些属性被开辟到堆区了,所以程序必须要走子类中的析构代码,如果使用多态是走不到的,所以我们才在父类中加上(纯)虚析构。使用(纯)虚析构,就是为了解决子类析构代码调用不到的问题。虚析构或纯虚析构就是用来解决通过父类指针释放子类对象如果子类中没有堆区数据,可以不写为虚析构或纯虚析构。

兴趣使然的编程菜鸟 817

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

父类指针可以指向子类对象,反之则不能。

父类指针可以指向子类对象,反之则不能 最近准备考研复试内容,都是c/c++选择题,做点笔记。 转载自:父类指针可以指向子类对象,反之则不能 简单来说,C++的多态就是靠父类指针指向子类对象+虚函数来实现的。父类指针指向子类对象,可以调用子类从父类继承来的那一部分,但如果父类中声明了virtual,则可以调用子类中的方法,这样就实现了多态。而子类指针指向父类对象,可能会调用到父类中没用的方法,因此这...

Creep_的博客 867

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

vector父类类型可以存放子类吗_C++小知识系列之“父类指针”和dynamic_cast!

“OLDPAN博客”,侃侃而谈人工智能深度酝酿优质原创文!阅读本文需要1X分钟 ?什么是父类指针父类指针也可以称为基类指针,当父类(基类)指针指向派生类(子类)指针的时候,可以触发“多态的效果”。不过本文的重点不在“多态”,而是聊聊当父类指针和子类指针互相赋值时需要注意的问题。你懂得废话不多说,直接看代码~假设我们有两个类,一个是Base父类,另一个是Derived子类。class...

weixin_39757739的博客 1847

父类指针和子类指针的步长

这一节是一个主意点 阅读下面代码: #include "stdafx.h" #include &lt;iostream&gt; using namespace std; class Father { public: Father(int a) { this-&gt;a = a; } virtual void Print() { cout &lt;&lt; "Father...

zzyczzyc的博客 308

C++中父类指针步长和子类指针步长

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_33824363的博客 217

多态(上)【C++】

在C++中,虚函数是使用virtual关键字修饰的非静态成员函数。虚函数的主要作用是允许在派生类中重新定义基类的函数,从而实现多态。关于虚函数的一些注意点:虚函数就是为了实现多态而存在的,而且支持虚函数是需要付出一定代价的所以如果不实现多态,就不要定义虚函数静态成员函数不能做虚函数因为①虚表指针存在对象里,但是静态成员的生命周期比对象长,而且静态成员函数里面没有this指针,就找不到对象②因为静态的特性:在以该父类为起始的整个继承体系中只有一份,如果实行多态的话就有多份了,这不符合静态的特性。

2301_80058734的博客 1938

多态中的指针

一、父类指针指向子类对象 首先,来看一段代码: //用父类指针指向子类对象 class A { public: A() { printf("A \n"); } ~A() { printf(" ~A \n"); } // 这里不管写不写virtual,删除B对象的时候,都会被执行。因为这个例子是B*指针指向B对象,不是A*指针指向B对象。 }; class B : public A { pu...

小时候挺菜的博客 1484

C++中的虚函数表

面试中遇到最多的问题就是多态的概念,以及多态的实现依据,首先多态发生的条件: (1)必须要有子类继承父类 (2)父类中存在虚函数,并且子类重写该虚函数 (3)父类的指针或者引用指向子类对象 这三个条件缺一不可。那么多态究竟是怎么实现的呢?那就不得不提到虚函数表,在每一个实例化的子类对象的头部,首先是一个指向虚函数表的指针,那么虚函数表中依次存放着父类的方法和子类特有的方法,如果子类重写父类的方法,那么就会替换父类的方法,否则的话就照抄。下面给出一个示意图。 这里面需要注意的是,虚函数表并不是共.

littlecorner1205的博客 2114

基类与派生类,父类指针指向子类对象

先来看一段程序: #include using namespace std; class Base_J { public: Base_J() { cout << "Base Created" << endl; } ~Base_J() { cout << "Base Destroyed" << endl; } }; class Derived_J : public Ba

wangzengdi的专栏 1万+

实现多态,必须通过指针或者引用去操作对象,如果直接操作对象,它的类型就已经为编译器所知,也就无法实现多态了。

父类的指针是可以指向子类类型的,父类对象也是可以引用子类对象的通过这个可以让父类使用子类的方法,这个就是多态这个和继承的内存构建有关class  A {...};class  B : public A {...};如果生成一个B的对象b,是先构建A再构建B,b的内存空间结构就是A在上B在下所以A的指针是可以指向b的(子类)的指针不能指向A(父类)的对象子类的内存空间通常大于父类,如果子类的指针指向...

qq_35826851的博客 1017

C++:多态(原理篇)

全网最细多态原理讲解,创作不易,求求佬们多多支持❤️❤️❤️

Jdxxwu的博客 1287

多态 父类指针与子类指针的步长不一致

多态时 子类与父类指针步长不一致

weixin_41377572的博客 111
上一篇: 多态场景的一个坑
下一篇: 进程基本概念
bugu___
博客等级 码龄2年 63粉丝 28原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值