簡體   English   中英

C ++指針多繼承的樂趣

[英]C++ pointer multi-inheritance fun

我正在編寫一些涉及從基本引用計數指針類繼承的代碼; 並且出現了一些復雜的C ++。 我把它減少如下:

假設我有:

class A{};
class B{};
class C: public A, public B {};

C c;
C* pc = &c;
B* pb = &c;
A* pa = &c;

// does pa point to a valid A object?
// does pb point to a valid B object?

// does pa == pb ?

此外,確實:

// pc == (C*) pa ?
// pc == (C*) pb ?

謝謝!

  • pa指向有效的A對象?
  • pb是否指向有效的B對象?

是的, C*被轉換,以便papb指向正確的地址。

  • pa == pb?

不,通常不是。 在同一地址不能有A對象和B對象。

此外,是嗎

  • pc ==(C *)pa?
  • pc ==(C *)pb?

強制轉換將指針轉換回C對象的地址,因此兩個等式都為真。

C嵌入AB

class C: public A, public B {};

與C代碼非常相似

struct C {
    A self_a;
    B self_b;
};

(B*) &c; 相當於static_cast< B* >( &c )類似於&c.self_b如果你直接使用C.

通常, 您不能依賴指向不同類型的指針,這些指針是可互換的或可比較的。

pc == pa;
pc == pb;

未定義,取決於類結構。

pc == (C*) pa;
pc == (C*) pb;

沒關系。

pa == pb;

沒有。

他們指向有效的對象嗎?

Yes

項目28 C ++ 中指針比較的含義 常識:基本中間編程 )解釋了C ++中對象指針的關鍵:

在C ++中,對象可以有多個有效地址,指針比較不是關於地址的問題。 這是一個關於對象身份的問題。

看看代碼:

class A{};
class B{};
class C: public A, public B {};

C c;
C* pc = &c;
B* pb = &c;
A* pa = &c;

class C源自class Aclass B ,因此class C class A既是class A class B 對象C c有3個有效地址: class A class B class Cclass C class B地址。 實現依賴於編譯器,因此您不能假設class C的內存布局,它可能是這樣的:

 ----------  <- pc (0x7ffe7d10e1e0)
 |        |
 ----------  <- pa (0x7ffe7d10e1e4)
 | A data |
 ----------  <- pb (0x7ffe7d10e1e8)
 | B data |
 ----------
 | C data |
 ----------

在上面的例子中,盡管pcpapb的地址值不相同,但它們都引用相同的對象( c ),因此編譯器必須確保pc比較等於papb ,即pc == papc == pb 編譯器通過調整被比較的指針之一的值通過適當的偏移量來完成此比較。 例如,

pc == pa

被翻譯成:

pc ? ((uintptr_t)pc + 4 == (uintptr_t)pa) : (pa == 0)

除此之外,由於AB沒有繼承關系,我們無法直接比較papb

對於你的問題:

(1) does pa point to a valid A object?  
(2) does pb point to a valid B object?  
Yes, refer the above diagram. 

(3) pc == (C*) pa ?  
(4) pc == (C*) pb ?  
Yes, No need to add (C*).

(5) does pa == pb ?
No. We can't compare them.

你得到的是記憶中的這樣的東西

 ----------
 | A data |
 ----------
 | B data |
 ----------
 | C data |
 ----------

因此,如果您想要整個C對象,您將獲得指向內存開頭的指針。 如果您只想要A“部分”,那么您將獲得相同的地址,因為數據成員所在的地址。 如果你想要B“部分”你得到開頭+ sizeof(A)+ sizeof(無論編譯器為vtable添加什么)。 因此,在這個例子中,pc!= pb(可能是pc!= pa)但是pa永遠不等於pb。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM