2010-03-12 79 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; 
    // ... 
};