2011-03-04 83 views
0

假設我有以下層次:簡單的繼承問題

class A 
{ 
public: 
A() 
private: 
int aa; 
} 

class B: public A 
{ 
public: 
B() 
private: 
int bb; 
} 

class D: public B 
{ 
public: 
D() 
private: 
int dd; 
} 

當我在下面的代碼輸入我的主:

D dobj; 
std::cout<<"Address of D object: "<<&dobj<<std::endl; 

A aobj = static_cast<A>(dobj); 
A* aptr = static_cast<A*>(&dobj); 

std::cout<<"Address of D object: "<<&dobj<<std::endl; 
std::cout<<"Address of aptr object: "<<&aptr<<std::endl; 
std::cout<<"Address of A object: "<<&aobj<<std::endl; 

的輸出是:

Address of dobj object: 0012FF0C 
Address of dobj object: 0012FF0C 
Address of aptr object: 0012FF18 
Address of aobj object: 0012FF14 

爲什麼aptr和aobj的地址不同?他們不應該是一樣的嗎?

而且爲什麼DOBJ和地址APTR不同?他們不是應該一樣嗎?

我編譯使用VC++的窗口。

感謝, 德Costo。

回答

6

爲什麼aptr&aobj不同?

首先,要打印出了錯誤的指針:&aptr是「的aptr地址」,而不是「對象到aptr點的地址。」您只需要打印aptr以打印「aptr要點的對象的地址」,這可能是您真正想要執行的操作。

aptr是指向dobjA部分的指針。 aobjdobjA部分的副本

aptr&aobj因爲它們是不同對象的地址不同。

+0

@de costo:首先,中投是不必要的:你可以隱式'd *'轉換爲'A *',所以你可以說'APTR = DPTR;'。這些指針可能具有相同的值:'aptr'將指向'D'對象的'A'基類部分。如果'A'基類部分位於'D'對象的開頭,那麼'aptr'將與'dptr'相同。 – 2011-03-04 23:05:36

+0

我的不好!感謝您指出,但是,如果我將它投射到B的指針,如下所示:B * bptr = static_cast (&dobj);)aptr和bptr的地址相同如果bptr指向D對象的B部分, B基類不在D對象的開始位置,應該不是aptr和bptr是不同的嗎? – 2011-03-04 23:11:32

+0

@de costo:'B'類被放在內存中,就像'[A base class] [bb member ]'和'D'類被放在內存中,如'[B base class] [dd member]'。這樣,給定'D x;',以下全部三個將給出相同的地址:(1) (2)'static_cast (x)'和(3)'static_cast (x)'。如果您使用Visual C++編譯(或在大多數其他編譯器上編譯),那麼在單繼承層次結構中你表明,基類應該總是位於派生類的開始處(它最終在繼承上下文更便宜itance層次結構)。 – 2011-03-04 23:14:45