2011-10-05 76 views
-4

編輯:
雖然格式錯誤這個問題有一個很好的catch.So,我編輯這在誰碰到這個問題絆倒以後的訪問者更好的格式保留此。向量變更類的大小


在下面的代碼示例可有人請解釋爲什麼不同階級的大小比memcpy結束後的預計?是什麼原因?

Here是Ideone的在線演示。

#include<iostream> 
#include<vector> 
#include<cstdio> 
#include<cstring> 

using namespace std; 

class A 
{ 
    public: 
     int a; 
     virtual void f1() { cout <<"inside a::f1\n"; } 
     A() { a = 1; } 
}; 

class B 
{ 
    public: 
     int b; 
     virtual void f2() { cout <<"inside b::f2\n"; } 
     virtual void f5() { cout <<"inside b::f5\n"; } 
     B() { b = 2; } 
}; 

class C : public A, public B 
{ 
    public: 
     int c; 
     void f1() { cout <<"inside c::f1\n"; } 
     void f2() { cout <<"inside c::f2\n"; } 

     virtual void f3() { cout <<"inside c::f3\n"; } 
     virtual void f4() { cout <<"inside c::f4\n"; } 
     C() { c = 3; } 
}; 


int fun() 
{ 
    int a = 1; 
    return a * 2; 
} 

int main() 
{ 
    C c; 
    C c2; 
    int (*g)() = &fun; 

    void (A::*g1)() = &A::f1; 
    void (C::*g2)(); 

    g2 = &C::f1; 
    (c.*g2)(); 

    printf("%p\n",g2); 
    cout << sizeof(g2) << endl; 

    g2 = &C::f2; 
    (c.*g2)(); 

    printf("%p\n", g2); 

    // Why is the output 1 here in g++ or visual C++? 
    cout << g2; 
    // Why is the sizeof returning 8? Please explain. 
    cout << sizeof(g2) << endl; 

    g2 = &C::f1; 
    std::vector<unsigned char> a_vec(sizeof(g2)); 

    memcpy(&a_vec[0], &g2, sizeof(g2)); 
    for(size_t i = 0; i < sizeof(g2); ++i)  
    {   
     cout << hex << static_cast<unsigned>(a_vec[i]) << " "; 
    } 
    cout << endl; 

    g2 = &C::f2; 
    std::vector<unsigned char> a_vec1(sizeof(g2)); 
    memcpy(&a_vec1[0], &g2, sizeof(g2)); 

    for(size_t i = 0; i < sizeof(g2); ++i)  
    {   
     cout << hex << static_cast<unsigned>(a_vec1[i]) << " "; 
    } 
    cout << endl; 

    cout << sizeof(g) <<endl; 
    cout << sizeof(g1) <<endl; 
    cout << sizeof(g2) <<endl; 

    // Why is sizeof(C) printing 14 and not 20 in visual C++? 
    // If yes why is this so ? 
    cout << sizeof(C) << endl; 
    cout << sizeof(c2) << endl; 
    cout << (&c) << endl; 
    cout << c.a << endl; 
    cout << c.b << endl; 
    cout << c.c << endl; 

    return 0; 
} 

從上面的代碼示例中,我得到的輸出是:

inside c::f1 
0x1 
8 
inside c::f2 
0x5 
18 
1 0 0 0 0 0 0 0 
5 0 0 0 0 0 0 0 
4 
8 
8 
14 
14 
0xbffe375c 
1 
2 
3 

以下是我的問題:

  1. 爲什麼輸出1這裏用g ++或Visual C++?

    cout < < g2;

  2. 爲什麼sizeof返回8?請解釋。

    COUT < <的sizeof(G2)< < ENDL;

  3. 爲什麼sizeof(C)打印在Visual C 14,而不是20 ++?如果是的話爲什麼這樣呢?

    COUT < <的sizeof(C)< < ENDL;

+0

請注意,如果memcpy代碼被註釋了,sizeof(C)將打印20,如果它未被註釋,則打印14 ..請解釋 –

+3

並至少提供一個問題... – RvdK

+4

請編輯您的問題,一些文本,解釋問題是什麼,輸出是什麼等等。解析這段長長的代碼來閱讀註釋並不是很好。 – Mat

回答

3

爲什麼sizeof返回8。請解釋?

cout <<sizeof(g2)<<endl; 

返回8因爲g2就在你enviornment的指針的指針和尺寸8.


爲什麼是輸出1這裏以g ++或Visual C++?

cout << g2; 

<< operator不具有重載的版本,其接受的指針。所以指針被轉換爲一個bool類型,值爲1,然後cout將其打印出來。

C++標準允許這樣的:

C++ 03標準4.12布爾轉換

1算術,枚舉,指針,或指向構件類型的右值可以被轉換爲一個bool類型的右值。


爲什麼sizeof(C)打印14和不20在Visual C++。

cout<<sizeof(C)<<endl; 

它顯示的C正確只是以十六進制(14 in hex == 20 in decimal)的大小。這是因爲您之前使用了hex I/O管理器來打印地址。

cout<<dec<<sizeof(C)<<endl; 

將重新設置I/O操作機械手小數模式,它將輸出20如您所願。


字約printf和類型安全:

printf沒有使用printf它是用戶的責任,以適當的formart描述符和數據類型傳遞給它輸入safe.When。如果不匹配,則會發生未定義行爲。未定義的行爲意味着程序可能會崩潰或顯示任何奇怪的行爲。

printf(「%p \ n」,g2);

是未定義行爲的一個示例,在格式描述符和數據類型中存在不匹配。請注意,編譯器會對此抱怨,並且應該始終注意並檢查編譯器發出的此類警告。

警告:格式 '%P' 預計類型 'void *的',但參數2具有輸入 '無效(C :: *)()'

+0

對於正常的函數指針,sizeof給出4 –

+0

@RishiMehta,因爲函數指針不是常規指針。在你的平臺上,它們恰好是4個字節。 –

+0

@Als很好的發現了布爾轉換。我錯過了。 –

0

sizeof結果對於給定類型從不改變。 (至少在一個 標準的C++程序G ++,我相信,支持沃拉斯在C++中,作爲 擴展和sizeof含有VLA對象可能會發生變化。) 至於您明確的問題:

printf("%p\n", g2); 

是未定義的行爲。您將指向成員的指針傳遞給輸出 格式器,該格式器需要void*。 (g ++會警告這一點,我相信,至少在某些選項上是這樣。)你可能會得到大約 任何東西(包括程序崩潰)。成員指針是不是 void*,並且不能轉換成void*

cout << g2; 

我不敢相信這個編譯。

cout << sizeof(g2) << endl; 

sizeof(g2)返回8,因爲這是一個指向成員 您的系統上的大小。

cout << sizeof(C) << endl; 

打印14,因爲這是在類型 C在你的系統上對象的十六進制的大小。換句話說,sizeof(C)是20.因爲你已經爲hex設置了輸出 ,並且永遠不會重置它,所以輸出是十六進制。