2014-03-07 87 views
10

我有這段代碼:爲什麼指向同一對象的指針具有不同的值?

#include <iostream> 

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 d; 
    A *b1 = &d; 
    B *b2 = &d; 

    std::cout << (long)b1 << std::endl <<(long)b2<< std::endl; 
} 

當編譯並運行它產生以下輸出:

140734705182320 
140734705182328 

它並不完全清楚爲什麼不同的指針指向同一個地址(& d)有不同的價值。

在此先感謝。

+0

因爲他們*不*指向同一個對象。 'b1'指向'A'對象,'b2'指向'B'對象。兩個類都不是另一個的子類型,所以都不能指向另一個的子對象。 – delnan

+1

指針確實有不同的地址,但這不是你的程序演示的內容。這表明他們*存儲了不同的地址。 –

+0

您應該將指針值轉換爲'void *',而不是'long',用於打印。 –

回答

12

一個C對象的存儲器佈局將是這樣的:

A base_object_1; 
B base_object_2; 
char m_c; 

兩個基礎對象具有不同的地址; A將(通常)具有與完整對象相同的地址,但B(通常)不會。當然,他們不能有相同的地址,除非至少有一個是空的。

因此,將指向完整對象的指針轉換爲指向其中一個基礎對象的指針必須更改指針值才能指向正確的地址。

+0

有趣的是,'C * b3 =&d;'將指向與'b1'相同的地址。並且要完全清楚:如果您更改示例以便'B'從'A'繼承(而'C'只能直接從'B'繼承),那麼'b1','b2'和'b3'具有相同的值。 – CompuChip

+0

@CompuChip:確實;儘管這兩種語言都沒有保證。 –

+0

確切的,你也不應該在乎。你使用一個指向'C'實例的'A'指針的原因是你可以在不知道它的運行時類型的情況下訪問它的''A'接口 - 而不是你可以指向它的魔術(又名算術) :) – CompuChip

相關問題