能否根据C++ 对象成员的地址计算出对象自己的地址

luuillu 2017-01-07 05:16:20

class Base{
public:
Base (): count(0) {}
int count;
};

class Derived: public Base{
public :

class Test1{
public:
Test1(){
Derived* pd = 0;
Test1* pt1 = &(pd->test1);

Derived* pDrive = (Derived* )(this - pt1);

++pDrive->count;
}
} test1;
};

int main(int argc, char **argv) {
Derived d;
std::cout<<"count="<<d.count<<std::endl; // 输出count=1
}


以上代码在gcc上编译后,能够正常执行, 这是不是巧合?同一个C++类创建的两个实例的内存布局方式是否一定相同?


...全文
343 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2017-01-09
  • 打赏
  • 举报
回复
《深度探索C++对象模型》 《C++反汇编与逆向分析技术揭秘》
Dobzhansky 2017-01-09
  • 打赏
  • 举报
回复
宏CONTAINING_RECORD 根据结构体中的某成员的地址来推算出该结构体整体的地址
Dobzhansky 2017-01-09
  • 打赏
  • 举报
回复
c 的结构体可以用 CONTAINING_RECORD
lunat 2017-01-09
  • 打赏
  • 举报
回复
linux内核里面到处都是container_of。但它的使用环境是C语言结构体。 楼主你的需求,只要确保数据传输的两端使用同样的内存布局去表示相同的数据就可以了。 最简单的做法是定义packing(1)的结构体,然后两端使用相同的头文件。发送方直接复制结构体内存,接收方直接强转成结构体指针。
paschen 版主 2017-01-08
  • 打赏
  • 举报
回复
可以啊,你只需要知道这个成员与这个对象的偏移就行 而这个偏移量可以用offsetof宏得到 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
ID870177103 2017-01-07
  • 打赏
  • 举报
回复
同一个类型的内存布局肯定是一样 其实底层c里面偶尔就有获得成员偏移的需求 stddef.h里就有这样一个宏
// Define offsetof macro
#if defined(_MSC_VER) && !defined(_CRT_USE_BUILTIN_OFFSETOF)
    #ifdef __cplusplus
        #define offsetof(s,m) ((size_t)&reinterpret_cast<char const volatile&>((((s*)0)->m)))
    #else
        #define offsetof(s,m) ((size_t)&(((s*)0)->m))
    #endif
#else
    #define offsetof(s,m) __builtin_offsetof(s,m)
#endif
luuillu 2017-01-07
  • 打赏
  • 举报
回复
引用 2 楼 jianwen0529 的回复:
同一个C++类创建的两个实例的内存布局方式是否一定相同? 这是当然的,要不然怎么能正确拷贝呢 这一句的结果是未定义的 Derived* pDrive = (Derived* )(this - pt1); 因为没有规定基类的Data必须放置在派生类独有的Data前面,另外还得考虑虚函数表的位置(甚至虚函数的实现是不是表也难说)等
谢谢 这句话并不涉及到基类, this 是成员变量的地址, ptr1 是成员变量相对所属对象的地址。 另外虚函数表的位置有什么影响?
luuillu 2017-01-07
  • 打赏
  • 举报
回复
谢谢 你说的术语是POD类型吧,显然这个不满足POD条件。 之所以要问这个问题,是因为我在工作中经常遇到一些实现协议的需求,要实现一个二进制协议,理论上只需要把每个字段的类型和名称描述出来就可以了。比如:

class SimpleResponse {
   int error_code;
   std:string error_message;
};
以往的做法是在写一个处理函数,把二进制中的值解析出来,然后复制给各个成员。我想把这个处理函数省略掉,提高写代码速度 期望的结果是,实现一个通用的模板,然后把上面定义的类传过去,可以自动把二进制协议解析出来,填写到SimpleResponse的对象的对应成员中。 我在尝试写这个模板的时候发现一个问题:没有办法枚举类各个成员变量。 如果楼主层 给出的代码是合法C++代码,那么就可以让成员变量把自己注册到外部类的容器(比如ArrayList)中,就能实现枚举类的成员变量的功能。
幻夢之葉 2017-01-07
  • 打赏
  • 举报
回复
同一个C++类创建的两个实例的内存布局方式是否一定相同? 这是当然的,要不然怎么能正确拷贝呢 这一句的结果是未定义的 Derived* pDrive = (Derived* )(this - pt1); 因为没有规定基类的Data必须放置在派生类独有的Data前面,另外还得考虑虚函数表的位置(甚至虚函数的实现是不是表也难说)等
幻夢之葉 2017-01-07
  • 打赏
  • 举报
回复
看 深度探索C++对象模型 这本书 标准并不规定对象的内存布局如何实现,由各个厂商自行制定 兼容C struct的标准布局除外(那个术语叫什么不记得了,是类成员布局的特例)

64,323

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧