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/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千里马学框架

帮助你了,就请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值