2010-03-12 114 views
2

我:成员变量的C++偏移量?

class Foo { 
    int a; 
    int b; 
    std::string s; 
    char d; 
}; 

现在,我想知道的偏移,B,S,D给出一个Foo *

即假设我有:

Foo *foo = new Foo(); 
(char*) foo->b == (char*) foo + ?? ; // what expression should I put in ? 
+12

为什么要这样? – Naveen 2010-03-12 06:44:42

+1

而且,你想要什么,编译时或运行时? – Arun 2010-03-12 07:00:02

+0

你的意思是让会员私密吗? (你不应该要求这个规避访问说明符。) – visitor 2010-03-12 09:57:18

回答

7

我并不确切地知道你为什么要补偿一员的你struct,但偏移的东西,允许获得一个指向给定结构的地址成员。 (请注意标准的offsetof宏只适用于POD结构(不属于你的),所以这里不是合适的答案。)

如果这是你想要做的,我会建议使用指针 - 因为这是一种更便携的技术。例如

int main() 
{ 
    int Foo::* pm = &Foo::b; 

    // Pointer to Foo somewhere else in the program 
    extern Foo* f; 

    int* p = &(f->*pm); 
} 

注意,如果b不是私人的Foo这只会工作,或替代你可能形成的Foo一个成员函数或朋友的成员指针。

+1

我想不出C++标准制造商将POF类型的偏移限制在一个令人信服的原因,但它似乎与许多编译器产生了预期的结果。所以它可能会工作,但将是不可移植的。 – 2010-03-12 09:24:39

+4

@Dan,实际上C++ 0x允许将它应用于非POD,只要该类型是标准布局类型即可。 – 2010-03-12 23:02:27

1

您应该考虑到结构内的偏移量是依赖于编译器的。不同的编译器可以将填充零置于零,或者不仅在结构的末尾,而且甚至在结构的中间(尽管我认识到这一点更为罕见)。即,直接用偏移量搞乱而不是以“标准方式”访问成员的结果是未定义的行为。

Charles Balley给出的解决方案更为合理。无论如何,我不太明白你的问题的最终目标是什么。具体而言,

Foo *foo = new Foo(); 
(char*) foo->b == (char*) foo + ?? ; 

根本没有意义。你是否想将foo内部的偏移赋值给foo?

也许你正在尝试做的是使用内部B富作为一个char *,在这种情况下,问题是:

Foo *foo = new Foo(); 
char* ptr == (char*) foo + ?? ; 

也许你有时要正确对待B中一个int,有时作为char *,在这种情况下,您可以尝试进行以下更改(假设您只是忘记了公开):

class Foo { 
public: 
    int a; 
    union b { 
     int intB; 
     char * chrB; 
    } 
    int c; 
    // ... 
};