C ++:指向数据成员地址疑问的指针

编程入门 行业动态 更新时间:2024-10-28 02:35:54
本文介绍了C ++:指向数据成员地址疑问的指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我已经读过(C ++对象模型),C ++中的数据成员的指针的地址是数据成员的偏移加1? 我在VC ++ 2005上尝试这个,但是我没有得到偏移值。 例如:

类X { public: int a; int b; int c; } void x(){ printf(a的偏移量=%d,b =%d,c =%d,& X :: a, & X :: b,& X :: c); }

应打印偏移a = 1,b = 5,c = 9。但在VC ++ 2005中出现的是a = 0,b = 4,c = 8。 我不能理解这种行为。 摘自书: / p>

然而,这个期望是由一个C和C ++程序员的一个传统错误。

如果vptr放置在结尾或4,8和12,如果vptr放置在类的开始处,则类布局内的三个坐标成员的物理偏移分别为0,4和8 。然而,获取成员的地址返回的值总是被加1.因此,实际值为1,5和9,等等。 问题是区分指针没有数据成员和指向第一个数据成员的指针。例如:

float Point3d :: * p1 = 0; float Point3d: :* p2 =& Point3d :: x;

// oops:如何区分? if(p1 == p2){ cout<<p1& p2包含相同的值 - ; cout<<他们必须处理相同的成员!<<< endl; } 为了区分p1和p2,每个实际成员偏移值被加1.因此,编译器(和用户)必须记住减去1,然后才实际使用该值来寻址成员。

解决方案

东西的偏移是从一开始就有多少单位。第一件事是 开始,所以它的偏移量为零。

考虑你的结构在内存位置100:

100:class X {int a; 104:int b; 108:int c;

如您所见, a 与整个结构的地址相同,因此其偏移量(您要添加到结构地址以获取项目地址)为0。

注意ISO标准没有指定项目在内存中的布局。填充字节创建正确的对齐肯定是可能的。在假设的环境中,int只有两个字节,但它们所需的对齐方式是256字节,它们不会在0,2和4,而是在0,256和512。

而且,如果你正在从中截取的书真的是在C ++对象模型

这是来自'96的事实,并讨论了C ++下的内部结构(打蜡的抒情的知道是多么好是知道在 vptr 是,缺少整个点,这是在错误的抽象级别工作,你应该永远不关心)日期。事实上,介绍甚至陈述解释面向对象特征的基本实现 ...(我的斜体)。

事实上,没有人可以在ISO标准中找到任何东西,说这种行为是必需的,而事实上,没有MSVC不gcc行为这种方式,导致我相信,即使这是真的在一个特定的实现远在过去,它的不是真的(或要求是真实的)。

作者显然领导了2.1和3支队伍,虽然这本书似乎有历史价值,认为它与现代C ++语言(和实现)相关,至少我读过的那些位。

I have read(Inside C++ object model) that address of pointer to data member in C++ is the offset of data member plus 1? I am trying this on VC++ 2005 but i am not getting exact offset values. For example:

Class X{ public: int a; int b; int c; } void x(){ printf("Offsets of a=%d, b=%d, c=%d",&X::a,&X::b,&X::c); }

Should print Offsets of a=1, b=5, c=9. But in VC++ 2005 it is coming out to be a=0,b=4,c=8. I am not able to understand this behavior. Excerpt from book:

"That expectation, however, is off by one—a somewhat traditional error for both C and C++ programmers.

The physical offset of the three coordinate members within the class layout are, respectively, either 0, 4, and 8 if the vptr is placed at the end or 4, 8, and 12 if the vptr is placed at the start of the class. The value returned from taking the member's address, however, is always bumped up by 1. Thus the actual values are 1, 5, and 9, and so on. The problem is distinguishing between a pointer to no data member and a pointer to the first data member. Consider for example:

float Point3d::*p1 = 0; float Point3d::*p2 = &Point3d::x;

// oops: how to distinguish? if ( p1 == p2 ) { cout << " p1 & p2 contain the same value — "; cout << " they must address the same member!" << endl; } To distinguish between p1 and p2, each actual member offset value is bumped up by 1. Hence, both the compiler (and the user) must remember to subtract 1 before actually using the value to address a member."

解决方案

The offset of something is how many units it is from the start. The first thing is at the start so its offset is zero.

Think in terms of your structure being at memory location 100:

100: class X { int a; 104: int b; 108: int c;

As you can see, the address of a is the same as the address of the entire structure, so its offset (what you have to add to the structure address to get the item address) is 0.

Note that the ISO standard doesn't specify where the items are laid out in memory. Padding bytes to create correct alignment are certainly possible. In a hypothetical environment where ints were only two bytes but their required alignment was 256 bytes, they wouldn't be at 0, 2 and 4 but rather at 0, 256 and 512.

And, if that book you're taking the excerpt from is really Inside the C++ Object Model, it's getting a little long in the tooth.

The fact that it's from '96 and discusses the internals underneath C++ (waxing lyrical about how good it is to know where the vptr is, missing the whole point that that's working at the wrong abstraction level and you should never care) dates it quite a bit. In fact, the introduction even states "Explains the basic implementation of the object-oriented features ..." (my italics).

And the fact that nobody can find anything in the ISO standard saying this behaviour is required, along the fact that neither MSVC not gcc act that way, leads me to believe that, even if this was true of one particular implementation far in the past, it's not true (or required to be true) of all.

The author apparently led the cfront 2.1 and 3 teams and, while this books seems of historical interest, I don't think it's relevant to the modern C++ language (and implementation), at least those bits I've read.

更多推荐

C ++:指向数据成员地址疑问的指针

本文发布于:2023-07-28 02:47:27,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1226591.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:指针   疑问   成员   地址   数据

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!