簡體   English   中英

從派生對象獲取基礎對象的地址

[英]Get address of base object from derived object

我的程序中出現一個非常混亂的錯誤。 我認為我可能在同一類中有兩個不同的對象,而我以為我有相同的對象。 這很令人困惑,因為我正在處理一個非常大的框架,在該框架中很難獲得指向所需對象的指針。

我的問題是,如果我有一個繼承自Base的Derived類,並且有一個指向Derived對象的指針,我如何從該派生對象中獲取Base對象的地址? 我正在使用基類的源代碼,並在基類中打印出“ this”的地址。 在我的代碼的另一部分中,檢索指向派生對象的指針。 我需要能夠通過我的派生對象打印基礎對象的地址,以確定我是否有指向所需的特定派生對象的指針。

我可能對地址在繼承中的C ++工作方式有很大的誤解。 也許它們只是一個對象,而不是鏈接到派生對象的基礎對象?

非常感謝你

編輯:我想這樣做的原因純粹是為了調試。 問題是我正在使用的代碼庫不包含許多接口或受保護的成員,因此我必須編輯源代碼才能訪問某些信息。 但是,當我使用特定的Derived指針調用添加到Base類的方法時,程序崩潰。 在這種情況下,我需要能夠打印基礎對象的地址,以便可以確定這是正確的對象還是因為我實際上有一個指向錯誤對象的指針而出現此錯誤。 我意識到我可以將代碼添加到派生類中,以使其打印其地址,但是我只是想知道是否有可能在不編輯源代碼的情況下獲得該地址。 謝謝

從指向派生類的指針到指向基類的指針很容易:

Derived * derived_ptr = < some pointer >;
Base * base_ptr = derived_ptr;

如果您想做書呆子,可以在作業的右側使用static_cast

Base * base_ptr = static_cast<Base*>(derived_ptr);

從指向基類的指針到派生類的指針使用dynamic_cast

Derived * derived_ptr = dynamic_cast<Derived*>(base_ptr);

但是,這並不總是有效。 您需要啟用運行時typeid,並且基類至少需要一個虛擬方法。

在執行此操作之前,為什么需要從基本指針轉到派生指針? 這可能是您可能需要重新考慮設計的線索。

只有一個對象,它由一個Base和一個Derived組成-也就是說,在大多數實現中,該Base放在Derived旁邊的內存中。 這意味着在一般情況下,Base *與Derived *不同,但是它們將非常接近。

現在,您可以從Derived *輕松獲取Base *,強制轉換是隱式的,但您也可以使其明確:

Derived* dptr = ...;
Base* ptr = dptr;

但是,沒有什么可以阻止單個派生對象包含多個 Base對象。 通常情況並非如此,但可能會發生。 這意味着您無法比較Base指針,並且期望知道您是否在處理同一對象,而僅是同一Base子對象。

在單繼承的簡單情況下,對於大多數編譯器:

如果您有一個指向派生類的指針,則與指向基類的指針相同。 兩個指針具有相同的值,並指向相同的內存地址。

在內存中,如果您創建派生類的實例,則它將作為基礎對象的成員布置,然后是派生對象的成員。 基類成員構成派生對象的一部分。

class Base
{
   int b;
};

class Derived : public Base
{
   int d;
};

在內存中,假設“派生”指針為0400。然后:

0400 byte 1 of b
0401 byte 2 of b
0402 byte 3 of b
0403 byte 4 of b
0404 byte 1 of d
0405 byte 2 of d
0406 byte 3 of d
0407 byte 4 of d

派生的對象由基本成員和派生的自身成員組成,這兩個對象的地址都始於0400。

恰好發生在0400,派生的基礎對象部分已定位。 因此,base和derived具有相同的地址。

暫無
暫無

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

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