簡體   English   中英

使用指向基本abstact類的指針訪問子類成員

[英]Accessing child class members using pointer to a base abstact class

class a //my base abstract class
{
public:
virtual void foo() = 0;
};

class b : public a //my child class with new member object
{
public:
void foo()
{}
int obj;
};

int main()
{
b bee;
a * ptr = &bee;
ptr->obj; //ERROR: class a has no member named "obj"
}

我的問題是,當我有一個指向子類(“a”)指向子類(“b”)對象的指針時,如何訪問“obj”成員? 我知道鑄造應該成功,但我正在尋找更好的解決方案。

您可以使用dynamic_cast<>運算符的指針轉換為a的指針b 只有當ptr指向的對象的運行時類型為b ,轉換才會成功,否則將返回空指針,因此您必須在轉換后檢查結果:

b* p = dynamic_cast<b*>(ptr);
if (p != nullptr)
{
    // It is safe to dereference p
    p->foo();
}

如果你可以保證ptr所指向的對象的類型是b ,但是,在這種情況下(因為不涉及虛擬繼承)你甚至可以使用static_cast<> ,這會產生較少的開銷,因為它是在編譯時執行的-時間。

b* p = static_cast<b*>(ptr);
// You are assuming ptr points to an instance of b. If your assumption is
// correct, dereferencing p is safe
p->foo();

你必須拋棄繼承層次結構。 您的案例是為了將dynamic_cast用於適當的類型而量身定制的,因為如果您嘗試實際投射的對象具有預期類型,則允許您以類型安全的方式進行檢查。

在GCC和Clang(以及我認為的Visual Studio中),您還可以使用以下語法糖

if (Derived* x = dynamic_cast<Derived*>(x)) {
     // do something with \c x now that we know its defined     
}

而在C ++ 11中,使用auto類型推理,甚至更好

if (auto x = dynamic_cast<Derived*>(x)) {
     // do something with \c x now that we know its defined     
}

最后,如果我們想限制為只讀訪問

if (const auto x = dynamic_cast<Derived*>(x)) {
     // read something from \c x now that we know its defined     
}

請注意,這很好地限制的范圍x到if語句(S),如果我們一個后做多個連續的dynamic_cast這往往是更方便使用的另一個里面if的和else if的。

暫無
暫無

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

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