簡體   English   中英

C++ 從基類指針訪問派生類成員

[英]C++ Access derived class member from base class pointer

如果我分配類Derived的對象(基類為Base ),並將指向該對象的指針存儲在指向基類的變量中,我如何訪問Derived類的成員?

下面是一個例子:

class Base
{
    public:
    int base_int;
};

class Derived : public Base
{
    public:
    int derived_int;
};

Base* basepointer = new Derived();
basepointer-> //Access derived_int here, is it possible? If so, then how?

不,您不能訪問derived_int因為derived_intDerived一部分,而basepointer是指向Base的指針。

你可以反過來做:

Derived* derivedpointer = new Derived;
derivedpointer->base_int; // You can access this just fine

派生類繼承基類的成員,而不是相反。

但是,如果您的basepointer指向Derived一個實例,那么您可以通過basepointer訪問它:

Base* basepointer = new Derived;
static_cast<Derived*>(basepointer)->derived_int; // Can now access, because we have a derived pointer

請注意,您需要先將繼承更改為public

class Derived : public Base

你正在這里的雷區跳舞。 基類永遠無法知道它實際上是派生類的一個實例。 最安全的方法是在基類中引入一個虛函數:

class Base 
{ 
protected:
 virtual int &GetInt()
 {
  //Die horribly
 }

public: 
 int base_int; 
}; 

class Derived : Base 
{ 
  int &GetInt()
  {
    return derived_int;
  }
public: 
int derived_int 
}; 

basepointer->GetInt() = 0;

如果basepointer指向Derived其他東西,您的程序將死得很慘,這就是預期的結果。

或者,您可以使用dynamic_cast<Derived>(basepointer) 但是您需要在Base中至少有一個虛函數,並准備好遇到零。

static_cast<> ,就像一些人建議的那樣,是一種肯定的方式來射擊自己的腳。 不要對“C 語言家族的不安全性”恐怖故事的大量緩存做出貢獻。

你可以使用CRTP

您基本上在基類的模板中使用派生類

通過讓基類知道派生類的類型是可能的。 這可以通過使基類成為派生類型的模板來完成。 這個 C++ 習慣用法稱為奇怪的重復模板模式

知道派生類,基類指針可以靜態轉換為指向派生類型的指針。

template<typename DerivedT>
class Base
{
public:
    int accessDerivedField()
    {
        auto derived = static_cast<DerivedT*>(this);
        return derived->field;
    }
};


class Derived : public Base<Derived>
{
public:
    int field;
};

int main()
{
    auto obj = new Derived;
    obj->accessDerivedField();
}

//如果你知道你將使用哪個派生類

派生* 派生指針 = dynamic_cast < 派生 * > 基指針;

//然后你可以使用派生指針訪問派生類

暫無
暫無

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

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