2014-09-28 24 views
0

在Windows上的Visual Studio編譯器我有這樣的代碼:找出多態類型的C++指針是如何工作的?

#include <iostream> 
#include <string> 

class A 
{ 
public: 
    A() : m_i(0) { } 

protected: 
    int m_i; 
}; 

class B 
{ 
public: 
    B() : m_d(0.0) { } 

protected: 
    double m_d; 
}; 

class C : public A, public B 
{ 
public: 
    C() : m_c('a') { } 
private: 
    char m_c; 
}; 

int main() 
{ 
    C c; 
    A *pa = &c; 
    B *pb = &c; 

    std::cout << "&c address: " << &c << std::endl; 
    std::cout << "pa address: " << pa << std::endl; 
    std::cout << "pb address: " << pb << std::endl; 

    bool paSame(pa == &c); 
    bool pbSame = (pb == &c); 
    bool pbpaSame = (reinterpret_cast<char*>(pa) == reinterpret_cast<char*>(pb)); 

    std::cout << std::endl; 
    std::cout << "paSame: " << paSame << std::endl; 
    std::cout << "pbSame: " << pbSame << std::endl; 
    std::cout << "pbpaSame: " << pbpaSame << std::endl; 

    return 0; 
} 

現在,在我的電腦當我運行它,我得到這個輸出:

&c address: 0084FAA4 
pa address: 0084FAA4 
pb address: 0084FAAC 

paSame: 1 
pbSame: 1 
pbpaSame: 0 

爲什麼PA相同的& c和地址,是因爲在內存中的對象佈局中,A的數據最先出現?

我明白爲什麼pb被偏移8個字節,因爲它指向該類型的對象中的內存部分。打印出來的指針是不同的,但是這條線仍然評估爲真:

bool pbSame = (pb == &c); 

這是爲什麼?它是有道理的,因爲它們是同一個對象,但是這個規則是什麼?由於下一行(如預期的比較pa和pb的指針)顯示指針是不同的。

+0

這裏沒有多態類型。 – 2014-09-28 19:49:54

回答

1

由於自動轉換規則,表達式(pb == &c)的計算結果爲true。在進行比較之前,將&c轉換爲B*,其指向cB部分。

從C++標準草案N3337:

4.10指針轉換

3類型的prvalue「指針CVD」,其中D是一個類型,可被轉化到「指向cvB」的指針的預值,其中BD的基類(條款10)。如果BD不可訪問(第11章)或模糊(10.2)基類,則需要此轉換的程序不合格。轉換的結果是一個指向派生類對象的基類子對象的指針。

+0

無法理解/閱讀它:我瞭解到,它的說法是指針可以在從派生類到基類的情況下自動轉換,但在比較表達式中,不會從基類轉到派生類(這可能是錯誤的)對於自動轉換會是一個奇怪的選擇? – Chanakya 2014-09-28 20:15:01

+1

@Chanakya,'&c'的類型是'C *',它在比較之前轉換爲'B *'。它從派生類型指針自動轉換爲基類型指針。 – 2014-09-28 20:23:33