class和struct对变量的放置顺序是否有保证?

firendlys 2012-10-03 11:41:11
加精
由于某些特殊需要,我要在class或struct里面定义一个变量名不确定的指针变量.
所以,为了确定这个变量,我要求这个指针变量必须放在class或者struct的结尾处(开头的地方有特殊用途,不能放在开头)
同时,这个class或struct的大小是不确定的.

那么,我请问,可不可以通过直接定位到这个class最后的位置,来直接读写这个指针变量呢?

(我觉得,如果编译器在编译的时候对变量的定义顺序完全按照代码的顺序来编译,那么这种方法应该是可以的)

示例:

class CTest
{
public:
int a;
int b;
int c;
// 这里还有若干个变量,且个数和占用空间是不确定的.

void *ptr;//最后有一个指针,但这个指针的变量名是不确定的.
// 同时,这个指针也不能放在最开头的位置
};

int main()
{

//定义变量:
CTest test;

test.ptr = (void *) 0x123;//测试值

//读写ptr的方法:
void **thisptr = (void**) (((DWORD)&test) + (sizeof(CTest) - sizeof(void*)));
*thisptr = (void *) 0x456;

return 1;
};

//我想问一下,这种读写方法能不能在windows下正常使用?(包括 vs2003 ~ vs2012 )
//我目前只试过在 vc6 下通过.

//或者说,有没有更好的方法?


...全文
5398 132 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
132 条回复
切换为时间正序
请发表友善的回复…
发表回复
LAONINGA098 2012-10-30
  • 打赏
  • 举报
回复
感谢分享!
JonLee9527 2012-10-28
  • 打赏
  • 举报
回复
菜鸟飘过~~~
zhan750520 2012-10-26
  • 打赏
  • 举报
回复
学习。
fireampampice 2012-10-26
  • 打赏
  • 举报
回复
感谢分享
浩自为之 2012-10-26
  • 打赏
  • 举报
回复
lz这样用,面向对象就没饭吃了。。。呵呵
Daisy__Ben 2012-10-24
  • 打赏
  • 举报
回复

class ILastLocation{
public void* GetLastObjPtr() = 0;
};
class LastLocationImpl:public ILastLocation{
public void* GetLastObjPtr(){
return (void*)((INT_PTR)(this+1)-sizeof(void*));
}
}

就这样啦,lz需要调整了,太沉浸在项目中,容易迷失方向。
Daisy__Ben 2012-10-24
  • 打赏
  • 举报
回复
Very Easy! 继承虚函数,改写虚表,从而实现间接的跳转,要不搞几个Thunk给你?哇Hahaaaaa^
yeqishi 2012-10-23
  • 打赏
  • 举报
回复
学习了,顶
xiaohuh421 2012-10-23
  • 打赏
  • 举报
回复
变动的东西还是放在前面吧, 浪费点空间就可以了.

你说在头你已经有特殊作用了, 那难道不能再加点吗.
比如你在头4个字节有特殊用途,那么你可以再用接下来的4个表示你想要的数据啥.
如果你说你现在头的特殊用途也是不定长度的, 那么好吧, 因为这个指针只占4个字节,他们换个位置总可以吧.

变的尽量放到后面, 固定的都放到前面, 这样也符合扩展的需求.
KobeBryantLA 2012-10-23
  • 打赏
  • 举报
回复
很好!我这个初学者适用
x370542423 2012-10-22
  • 打赏
  • 举报
回复
mei you guan xi
BEANLIAO 2012-10-22
  • 打赏
  • 举报
回复
学习了
ying0620 2012-10-21
  • 打赏
  • 举报
回复
c++里好像没有反射?
huwenok 2012-10-21
  • 打赏
  • 举报
回复
元芳,把此事收集,稍后告诉坛主
hacker3344520 2012-10-20
  • 打赏
  • 举报
回复
踩踩踩,,,,,哈哈哈
G_cofa 2012-10-20
  • 打赏
  • 举报
回复
105 楼正解,提供函数接口来操作数据。即使是c,也应该提供一个函数。
G_cofa 2012-10-20
  • 打赏
  • 举报
回复
用byte流可以。

问题是8字节对齐,sizeof(CTest)-sizeof(void*)错了

如下

thisptr = (void**)((char*)&test + offsetof(CTest,ptr));
*thisptr = (void *) 0x456;
printf("%x\n",test.ptr);
或者
void* CTest::* ctest_ptr = &CTest::ptr;
test.*ctest_ptr = (void*)0x123;
printf("%x\n",test.ptr);

做这种事情之前最好先打印sizof
cout<<"sizeof(CTest):"<<sizeof(CTest)<<"\n";
cout<<"sizeof(void*):"<<sizeof(void*)<<"\n";
cout<<"offsetof(CTest::a):"<<(std::size_t)(offsetof(CTest,a))<<"\n";
cout<<"offsetof(CTest::b):"<<(std::size_t)(offsetof(CTest,b))<<"\n";
cout<<"offsetof(CTest::c):"<<(std::size_t)(offsetof(CTest,c))<<"\n";
cout<<"offsetof(CTest::d):"<<(std::size_t)(offsetof(CTest,d))<<"\n";
cout<<"offsetof(CTest::ptr):"<<(std::size_t)(offsetof(CTest,ptr))<<"\n";
并且用编译时assert防止出问题。
lhbobo129 2012-10-19
  • 打赏
  • 举报
回复
感谢这么精彩的讨论~
I_ask_who 2012-10-18
  • 打赏
  • 举报
回复
微软经常干这种事情,比如:

#define _ATL_PACKING 8
#define offsetofclass(base, derived) \
((DWORD_PTR)(static_cast<base*>((derived*)_ATL_PACKING))- \
_ATL_PACKING)


标准c语言也有类似offsetof宏,详见:

http://en.wikipedia.org/wiki/Offsetof
wangweijia11 2012-10-18
  • 打赏
  • 举报
回复
关于第一题,我这样不知道对不对:
一起来分享..一起来分享
加载更多回复(112)

65,186

社区成员

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

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