c++基础知识之父类地址和基类地址一定相同?

背景

hi,粉丝朋友们:
大家好!这两天在分析智能指针Refbase相关内容时候,debug打印相关记录一直有个颠覆我观念的问题一直让我无比纠结。
本质原因可能还是java代码的思维去理解c++导致的。
情况如下:
java代码

public class  A {
	func({
		Log.i("this= " +this )
	}
}

public class B extends A {
	func1() {
		Log.i("this= " +this )
	}
}

如果new B(),那么java中调用func和func1,打印的this指针肯定都是同一个

同样以这个思想去套c++,认为c++也一样。

具体问题

调试LayerHandle类时候
frameworks/native/services/surfaceflinger/FrontEnd/LayerHandle.h

class LayerHandle : public BBinder

发现是继承BBinder

class BBinder : public IBinder

BBinder又是继承IBinder

class IBinder : public virtual RefBase

IBinder又继承RefBase

这种层级较多,不过层级多不影响分析,我们用java思维当然可以认为RefBase里面的this和LayerHandle类中使用的this是同一个。

所以加如下打印:

LayerHandle::LayerHandle(const sp<android::SurfaceFlinger>& flinger,
                         const sp<android::Layer>& layer)
      : mFlinger(flinger), mLayer(layer), mLayerId(static_cast<uint32_t>(layer->getSequence())) {
              ALOGE(" LayerHandle::LayerHandle() %p getDebugName %s",this,mLayer->getDebugName());
      }

注意这里LayerHandle构造加了打印this地址

同样在Refbase本身因为有相关的地址打印:

void RefBase::incStrong(const void* id) const
{
    ALOGD("incStrong of %p from %p: cnt=%d\n", this, id, c);
}

是不是可以认为这里RefBase在incStrong of后面打印的this肯定和上面的LayerHandle打印的this一样?因为LayerHandle本身是RefBase的孙子类。

下面来看结果:

03-10 21:51:58.668   350   429 E SurfaceFlinger:  LayerHandle::LayerHandle() 0x73366d342210 getDebugName Surface(name=8fea5e0 StatusBar)/@0x22305c5 - animation-leash of insets_animation#132

可以看到LayerHandle的this地址是0x73366d342210

看看RefBase的打印


03-10 21:51:58.668   350   429 D RefBase : incStrong of 0x73366d342240 from 0x73366d342210: cnt=268435456

明显看到incStrong of 后面是0x73366d342240明显和0x73366d342210是有一定偏移的,不相等

这个是为啥????难道子类指针还和基类的指针不是一个东西,是分别指向两个对象?

验证是否真的不一样:

鉴于LayerHandle各种可能比较复杂考虑写个简单一些类来验证,看看难道子类和基类指针真的不一样?

class WeightClass : public RefBase
{  
public:  
        virtual void testVirtual();
        void printRefCount()  
        {   
        }  
};  

class StrongClass :  public WeightClass  //注意这里普通继承
{  
public:  
        StrongClass()  
        {  
                        ALOGW("Construct StrongClass Object. %p\n",this);  
        }  

        virtual ~StrongClass()  
        {  
        }
        void testVirtual() {

        }  
};  
void TestStrongClass(StrongClass* pStrongClass)  
{  
        sp<StrongClass> test = sp<StrongClass>::make();

}  
int main(int argc, char** argv)  
{  
        StrongClass* pStrongClass = new StrongClass();  
        TestStrongClass(pStrongClass);  
}
03-10 23:24:29.360  2482  2482 W weightpointer: Construct StrongClass Object. 0x781b7af54450

StrongClass Object对象的this打印为0x781b7af54450,RefBase中相关打印:

03-10 23:24:29.360  2482  2482 D RefBase : incStrong of 0x781b7af54450 from 0x781b7af54450: cnt=268435456

可以看到incStrong of 0x781b7af54450的this打印确实和 StrongClass Object的一模一样

那么问题来了?为啥上面的LayerHandle的this就是和Refbase的this不一样呢?

经过验证查询发现继承方式上有一点差别:

class IBinder : public virtual RefBase

这里的IBinder继承时候采用是virtual继承方式,那么我们来尝试修改成这个方式试试?

转变成虚继承方式:

class WeightClass : public RefBase
{  
public:  
        virtual void testVirtual();
        void printRefCount()  
        {   
        }  
};  

class StrongClass : virtual public WeightClass  //注意这里变成虚继承
{  
public:  
        StrongClass()  
        {  
                        ALOGW("Construct StrongClass Object. %p\n",this);  
        }  

        virtual ~StrongClass()  
        {  
        }
        void testVirtual() {

        }  
};  
void TestStrongClass(StrongClass* pStrongClass)  
{  
        sp<StrongClass> test = sp<StrongClass>::make();

}  
int main(int argc, char** argv)  
{  
        StrongClass* pStrongClass = new StrongClass();  
        TestStrongClass(pStrongClass);  
}

变成虚继承后的打印如下:

03-10 21:52:02.877  2270  2270 W weightpointer: Construct StrongClass Object. 0x728c48faa700
03-10 21:52:02.877  2270  2270 D RefBase : incStrong of 0x728c48faa708 from 0x728c48faa700: cnt=268435456

明显可以看到StrongClass的this地址 0x728c48faa700但是RefBase的地址是0x728c48faa708
果然不一样了。

虚继承相关知识:

这个属于c++里面比较少见基础知识:
https://blog.csdn.net/effort_study/article/details/119488496

本文章更多详细代码和资料需要购买课程获取

七件套专题:在这里插入图片描述
点击这里
https://mp.weixin.qq.com/s/Qv8zjgQ0CkalKmvi8tMGaw

hal+perfetto+surfaceflinger
https://mp.weixin.qq.com/s/LbVLnu1udqExHVKxd74ILg
在这里插入图片描述

私聊作者+v(androidframework007)

视频试看:
https://www.bilibili.com/video/BV1wc41117L4/

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于PHP的餐厅管理系统APP设计与实现

目 录 摘 要 I Abstract II 引 言 1 1 相关技术 3 1.1 MVC 3 1.2 ThinkPHP 3 1.3 MySQL数据库 3 1.4 uni-app 4 1.5 本章小结 4 2 系统分析 5 2.1 功能需求 5 2.2 用例分析 7 2.3 非功能需求 8 2.4 本章小结 8 3 系统设计 9 3.1 系统总体设计 9 3.2 系统详细设计 10 3.3 本章小…

【初始MongoDB】MongoDB的使用(对比MySQL)

MongoDB简介 1、NoSQL简介 NoSQL(NoSQL Not Only SQL)&#xff0c;意即反SQL运动&#xff0c;指的是非关系型的数据库&#xff0c;是一项全新的数据库革命性运动&#xff0c;早期就有人提出&#xff0c;发展至2009年趋势越发高涨。NoSQL的拥护者们提倡运用非关系型的数据存储…

你是否遭遇过管理多种远程连接的混乱场面,介绍你一款方便统一的管理神器:1Remote

网管小贾 / sysadm.cc 约瑟夫是一个外国小伙儿&#xff0c;金发碧眼高鼻梁&#xff0c;年岁在35左右。 那天与他短暂的相处令我印象深刻。 那是某一年的夏天&#xff0c;我去南方某岛游玩&#xff0c;在一处僻静的口袋公园中偶遇了约瑟夫。 他当时正坐在长椅上&#xff0c;摆…

Redis精讲

redis持久化 RDB方式 Redis Database Backup file (redis数据备份文件), 也被叫做redis数据快照. 简单来说就是把内存中的所有数据记录到磁盘中. 快照文件称为RDB文件, 默认是保存在当前运行目录. [rootcentos-zyw ~]# docker exec -it redis redis-cli 127.0.0.1:6379> sav…

matlab阶段学习笔记小节2

syms定义符号变量 求极限 第二题 第三题 limit(y,n,inf);求的的函数y关于自变量n在无穷处&#xff08;inf&#xff09;的极限 exp(2)即指数为2&#xff0c;底为e,也就是e^2 求导数 第一题 log(x)默认是以e为底的指数函数&#xff0c;也就是ln(x). 使用diff(f)对函数进行求…

机器视觉学习(一)—— 认识OpenCV、安装OpenCV

目录 一、认识OpenCV 二、通过pip工具安装OpenCV 三、PyCharm安装OpenCV 一、认识OpenCV OpenCV&#xff08;Open Source Computer Vision Library&#xff0c;开源计算机视觉库&#xff09;是一个跨平台的计算机视觉库&#xff0c;最初由威尔斯理工学院的Gary Bradski于199…

什么是序列化?序列化的作用是什么?Java 中如何实现序列化和反序列化?

一、序列化简述 序列化是指将结构化的数据( 例如对象 )转化成一个字符串 / 字节数组。转化过程中&#xff0c;不会造成数据信息部分丢失。 反序列化则为反向操作&#xff0c;将已经进行过序列化之后的数据还原回原本的结构化数据。正是序列化中需要保证转化之后的数据信息不会…

游戏 AI 在体育竞技游戏中的应用实践,通过 PVE 对抗规则AI+自博弈的方式,训练出了高强度、多风格策略的足球 SPG 对战 AI | 附方案详情及资料

AI 在体育竞技游戏&#xff08;SPG&#xff0c;Sports Game&#xff09;中的应用已经成为游戏厂商持续探索的领域之一。随 着人工智能技术的不断发展&#xff0c;越来越多的游戏开发商开始使用 AI 来提升游戏的真实感和沉浸感。 例如&#xff0c;在足球模拟游戏中&#xff0c…

SpringMVC10、拦截器

10、拦截器 10.1、概述 SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。开发者可以自己定义一些拦截器来实现特定的功能。 过滤器与拦截器的区别&#xff1a;拦截器是AOP思想的具体应用。 过滤器 servlet规范中的一部分&…

力扣每日一题 猜数字游戏 阅读理解

Problem: 299. 猜数字游戏 思路 &#x1f468;‍&#x1f3eb; 灵神 复杂度 Code class Solution {public String getHint(String secret, String guess) {int a 0;int[] cntS new int[10];int[] cntG new int[10];for(int i 0; i < secret.length(); i){if(secre…

小迪安全34WEB 攻防-通用漏洞文件上传黑白盒审计逻辑中间件外部引用

#知识点&#xff1a; 1、白盒审计三要素 2、黑盒审计四要素 3、白黑测试流程思路 #详细点&#xff1a; 1、检测层面&#xff1a;前端&#xff0c;后端等 2、检测内容&#xff1a;文件头&#xff0c;完整性&#xff0c;二次渲染等 3、检测后缀&#xff1a;黑名单&…

http升级https需要做什么

背景&#xff1a;随着现代网络时代的高速发展&#xff0c;网络安全方面的日益更新&#xff0c;实现网站https协议的数量也在不断增多&#xff0c;完善安全方面的因素也在逐步增加。 下面从最基础的网站http协议全面升级为https协议的流程做出说明。 目录 首先带大家一起先了解…

打包paddle 运行时出现RuntimeError: (PreconditionNotMet) 错误的解决

一、问题描述 一个自动化操作的项目&#xff0c;使用了paddle&#xff0c;由于第一次用pyinstaller打包paddle项目(为什么不用nuitka?打包时间太长啦&#xff0c;遇到问题解决一次&#xff0c;时间都非常的长&#xff0c;无奈只把自己开发的模块用nuitka进行了打包&#xff0…

SSM整合项目(Vue3 + Element - Plus 创建项目基础页面)

文章目录 1.配置Vue启动端口1.修改vue.config.js2.启动 2.安装Element Plus命令行输入 npm install element-plus --save 3.修改Vue3默认样式并自定义一个组件1.修改App.vue1.删除原有结构2.启动项目查看 2.修改HomeView.vue3.删除HelloWorld.vue组件4.创建一个组件 src/compon…

介绍Kanzi

Linux开发过程中使用的Kanzi 是一个由 Rightware&#xff08;现为 Thundersoft 的一部分&#xff09;开发的跨平台图形用户界面&#xff08;GUI&#xff09;框架。它主要用于设计、开发和部署在计算机、移动设备和嵌入式设备上的2D和3D用户界面。Kanzi 提供了一个现代化的内容创…

GO语言-切片底层探索(上)

1.前言 今天在力扣上写算法&#xff0c;遇到了一个比较"奇怪"的错误。由于自己使用了递归切片&#xff0c;导致一开始没有看明白&#xff0c;直到在自己电脑上进行debug的时候才反应过来&#xff0c;原因出在了哪里&#xff1f;下面会先进行错误的分析和纠正&#x…

物理机win10怎么与虚拟机win10共享文件

打开win10虚拟机点击虚拟机选项安装vmTools 安装完成后系统会重启重启后关机 点击编辑虚拟机设置 选项、共享文件夹、总是启用 接下来点击添加选择你要共享的文件点击确定 打开虚拟机点击此电脑 就会看到共享的文件夹啦

python 导入excel空间三维坐标 生成三维曲面地形图 5-3、线条平滑曲面且可通过面观察柱体变化(三)

环境 python:python-3.12.0-amd64 包: matplotlib 3.8.2 pandas 2.1.4 openpyxl 3.1.2 scipy 1.12.0 import pandas as pd import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D from scipy.interpolate import griddata from matplotlib.c…

基于微信小程序的校园跑腿小程序,附源码

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

SSM整合项目(添加家居)

文章目录 1.需求分析2.设计结构3.编写Service层1.创建文件夹2.FurnService.java3.FurnServiceImpl.java4.单元测试 FurnServiceTest.java5.指定默认图片位置1.Furn.java 为imgPath设置默认值2.Furn.java 的全参构造器内判断imgPath是否为空 4.返回json数据的通用类com/sun/furn…