栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

数据成员的访问

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

数据成员的访问

一、基础知识

  1. 成员变量最后获取的方式实际是成员变量的地址+成员变量的偏移。
  2. 成员变量的偏移如何获取. 1) (int)(&((class*)0)->mem) 原理就是成员变量实际位置是对象地址+成员偏移,如果成员偏移为0,则剩下的就是成员的偏移。因此将0转化为类对象,直接获取成员变量地址后强转为int输出。因为没有访问成员变量本身,只是获取了他的偏移,因此不会报错。2)reinterpret_cast(*(void**)(&(class::mem)))
  3. 打印偏移。printf(“%x”, &class::mem)

二、实践获取偏移

#include 
#include 
using namespace std;

class A
{
public:
	int a = 1;
};

class B
{
public:
	int b = 2;
};


class C :public A, public B
{

};

void funT(int C::* pCT, C* pC)
{
	printf("%p %pn", pCT, pC);
	std::cout << pC->*pCT << std::endl;
}

void fun(C* pC)
{
	int B::* pB = &B::b;
	printf("%p %pn", pB, pC);
	funT(pB, pC);
}

int main()
{
	C pC;
	fun(&pC);
}


测试是否如所想一样。
测试代码

#include 
#include 
using namespace std;

class A
{
public:
	int a = 1;
};

class B
{
public:
	int b = 2;
};


class C :public A, public B
{

};

void funT(int C::*pCT, C *pC)
{
	printf("%p %pn", pCT, pC);
	std::cout << pC->*pCT << std::endl;
}

void fun(C* pC)
{
	int B::* pB = &B::b;
	int offset = reinterpret_cast(*(void**)&pB);
	cout << offset << endl;
	int a = *((char*)pC + ((int)&((B*)0)->b));
	int b = *((char*)pC + ((int)&((B*)0)->b) + sizeof(B));
	cout << a << " " << b << endl;
	printf("%p %pn", pB, pC);
	funT(pB, pC);
}

int main()
{
	C pC;
	fun(&pC);
}




三、VS 内的 c++内存模型

class A
{
public:
    int _a{ 1 };
    virtual void funA() {}
};
class B : virtual  public A
{
public:
    int _b{ 2 };
    virtual void funB() {}
};
class C : virtual public  A
{
public:
    int _c{ 3 };
    virtual void funC() {}
};
class D : public B, public C
{
public:
    int _d{ 4 };
    virtual void funD() {}
};


int main()
{

}

class D size(36):
        +---
 0      | +--- (base class B)
 0      | | {vfptr}
 4      | | {vbptr}
 8      | | _b
        | +---
12      | +--- (base class C)
12      | | {vfptr}
16      | | {vbptr}
20      | | _c
        | +---
24      | _d
        +---
        +--- (virtual base A)
28      | {vfptr}
32      | _a
        +---

D::$vftable@B@:
        | &D_meta
        |  0
 0      | &B::funB
 1      | &D::funD

D::$vftable@C@:
        | -12
 0      | &C::funC

D::$vbtable@B@:
 0      | -4
 1      | 24 (Dd(B+4)A)

D::$vbtable@C@:
 0      | -4
 1      | 12 (Dd(C+4)A)

D::$vftable@A@:
        | -28
 0      | &A::funA


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1010227.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号