2013-10-15 100 views
4

因此private基類中的成員也在繼承類中,但不能在其中訪問,對吧?
它們實際上是在分配給繼承對象的內存中嗎?
爲什麼私人會員繼承?

+2

繼承是一種「is-a」關係,所以是的,基類所需的所有內存都是子類中所需的。 – clcto

回答

7

它們實際上在分配給繼承對象的內存中嗎?

是的,他們需要存在。私有成員是基類實現細節的一部分。沒有他們,一般來說,基類將無法運作(這就是他們首先存在的原因)。

將它們設置爲私有隻允許基類創建其實現,但不會將其公開給任何人,包括子類。

+1

除了這個好的答案,我會說,基本上當你有一個基類MyBase例如,它是由一些類MyDerived繼承(無論如何 - 公共,私有或保護),並且當你創建一個對象類型爲MyDerived,在內存中的對象佈局中,實際上會有一個MyBase類型的對象。所以簡單地說:MyDerived類型的每個對象都有一個MyBase類型的對象。 – BlackCat

+0

@BlackCat - Re *簡單地說:MyDerived類型的每個對象都有一個MyBase類型的對象。* Diamond繼承。假設B和C各自繼承了A,D從B和C繼承。至少嵌入在D類實例中的B和C對象中的一個不會在它們「內部」包含一個A對象。 –

+0

@David:B和C都有一個指向普通(共享)基類A對象的指針。儘管他們不一定有A級對象,但他們的行爲與他們的行爲一樣。 – Tomek

6

是的。剛剛例如,你可以使用一個公共職能從操縱私人數據的基類,甚至在派生類的一個實例:

class Base { 
    int x; 
public: 
    Base() : x(0) {} 
    void inc() { ++x; } 
    void show() { std::cout << x << "\n"; } 
}; 

class Derived : public Base { 
}; 

int main() { 
    Derived d; 
    d.show(); 
    d.inc(); 
    d.show(); 
} 

有了一個正常的編譯器,它必須顯示:

0 
1 

...顯示Base對象中的數據存在於Derived對象中,即使它不是(直接)可訪問的。如果編譯器可以確定它可以以某種方式爲程序產生正確的可觀察行爲,即使沒有包含以下內容的私有部分,也可以使用「as-if」規則:基類,那麼它可以自由地這樣做。最明顯的例子就是如果你在基類中包含了一些在實踐中從未使用過的東西(成員函數或數據)。

+0

如果你編譯成一個可分發的DLL,你怎麼知道一個特定的成員函數是否沒有被使用? – TemplateRex

+0

@TemplateRex:有可能它不能,所以在這種情況下,它很可能不會忽略它。 –

+0

我認爲一次派生類的根本問題在於它可以被再次繼承,而潛在的孩子是一個開放的集合。因此,除非'Derived'被標記爲'final',否則我不認爲編譯器可以將as-if規則應用於其類佈局。最重要的是,這組未來的呼叫者也是一個開放的集合。 – TemplateRex

2

是它們是,

當要構造的派生類的對象的所有基類的,首先被構造爲好。到達派生構造函數體前

class Base 
{ 
int x; 

public: 
    Base(int px) 
    : x(px) 
    { 
    } 
}; 

class Derived : public Base 
{ 
int y; 
public: 
    Derived(int px, int py) 
    : y(py), Base(px) 
    { 
    } 
}; 

這個例子編譯和作品,BASE是初始化(構造函數):

考慮這個例子。