2010-03-12 91 views
24
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? 
+3

你真的想要使用私有繼承嗎? – 2010-03-12 21:53:23

+1

有人給它添加一個語句終止符,我只改變一個字符。 – 2011-04-16 13:25:48

回答

38

任何成員,則無法訪問derived_int因爲derived_intDerived一部分,而basepointer是指向Base

你可以做,雖然它倒過來:

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

派生類繼承基類,而不是周圍的其他方式的成員。

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

請注意,您需要將自己的遺產改變爲public第一:

class Derived : public Base 

但是,如果你的basepointer指着的Derived一個實例,那麼你可以通過投訪問

+1

不應該使用dynamic_cast而不是static_cast? – 2010-03-12 22:09:05

+9

這取決於他是否知道它是否是「派生的」。如果你100%確定(因爲我們在這裏),那麼'static_cast'很好。 – 2010-03-12 22:14:18

+0

並不是每個人都意味着reinterpret_cast而不是static_cast?我很確定static_cast不會編譯。 – Balk 2012-03-16 14:42:45

9

你在這裏的雷區上跳舞。基類永遠不會知道它實際上是派生的實例。要做到這一點,最安全的方法是在基礎引入虛函數:

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點,其他的是一個派生出來的,你的程序將死可怕,這是預期的結果。

或者,您可以使用dynamic_cast(basepointer)。但是你至少需要一個基本的虛擬功能,並且準備遇到一個零。

static_cast <>正如一些人所暗示的那樣,這是一種在腳下自我射擊的好方法。不要爲「C語言家族的不安全」恐怖故事大量緩存作出貢獻。

+0

「或者,你可以使用dynamic_cast的(basepointer),但至少需要一個虛函數的基礎是什麼,以及準備遇到一個零。」 - >好點Seva.Liked它:) – mahesh 2010-04-16 08:58:20

+3

使用'static_cast'是不拍自己的腳的方式。我認爲你用C的明確演員記法'(T)x'來混淆它。另一方面'static_cast'是類型安全的,但'dynamic_cast'將返回一個空指針,如果它無法轉換,而'static_cast'將發出編譯器錯誤。 – 0x499602D2 2015-06-07 21:06:00

4

可以使用CRTP

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

3

它是通過讓基類可能知道派生類的類型。這可以通過將基類作爲派生類型的模板來完成。這個C++習慣用語叫做curiously recurring template pattern

瞭解派生類,基類指針可以靜態轉換爲派生類型的指針。

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(); 
} 
0

//如果你知道你要使用什麼樣的派生類

派生* derivedpointer = dynamic_cast的<派生*> basepointer;

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