2010-05-28 84 views
7

我正在爲即將到來的測試回答一些示例問題,而這個問題完全令我困惑。C++中的簡單繼承

考慮下面的代碼:

class GraduateStudent : public Student 
{ 
    ... 
}; 

如果「公」字省略,GraduateStudent使用私有繼承,這意味着它的下面?

  1. GraduateStudent對象可能無法使用Student方法。

  2. GraduateStudent無權訪問Student的私人對象。

  3. 沒有方法GraduateStudent可能會調用Student的方法。

  4. 只有const方法GraduateStudent可以調用方法Student

+4

您對這件事有什麼想法? – 2010-05-28 14:27:20

+4

+1,明確表示這是作業。 – Kena 2010-05-28 14:33:46

+0

我明白你不想回答作業問題。我確實想到了這一點,而且我知道在私底下,基類的公共和私有方法都是派生類中的私有方法。課程筆記還提到了一些關於「派生類可以使用它們,但是它們不能從派生類的實例中喚起的東西」,我並沒有完全理解它。 – xbonez 2010-05-28 14:37:00

回答

22

雖然這是一個沒有功課的問題,但我會回答它,因爲這是一個可怕的問題。我幾乎認爲這是一個詭計的問題,它並不真正考驗知識。

答案是2. GraduateStudent不能訪問Student的私人對象。,除了這與私人繼承沒有任何關係。無論public關鍵字是否存在,第2點都是正確的,因爲派生類從不有權訪問其基類的私有成員,無論它們是如何繼承的。

私有繼承基本上意味着兩件事情(相對於公有繼承):

  1. GraduateStudentStudent成爲私有方法的所有公共方法。這意味着如果例如Student具有公開方法foo(),則GraduateStudent具有私人方法foo()

  2. 基類「無法訪問」,這意味着多態不起作用。通俗地說,這意味着如果GraduateStudent私自從Student繼承,那麼您不能將GraduateStudent*視爲Student*(或GraduateStudent&就好像它是Student&一樣)。

這個問題的作者也有可能指出,第1點是正確的答案,但它的措辭含糊不清。什麼意思是「GraduateStudent對象可能不使用Student的方法」?這有可能是意圖是這意味着你不能調用從Student繼承了GraduateStudent類型的對象的方法,就像我在上面第一點寫,但GraduateStudent對象本身,它的方法,可以使用方法Student

例如:

class Student { 
    public: 
    void foo() {}; 
}; 

class GraduateStudent : Student { 
    public: 
    void bar() 
    { 
    foo(); // Legal 
    } 
}; 

int main() { 
    GraduateStudent g; 

    g.bar(); // Legal 
    g.foo(); // Illegal 

    return 0; 
}; 
+1

正確 - 它讓我懷疑這個問題的作者是否意味着(1)是正確的答案,但只是措辭很糟糕。 – sechastain 2010-05-28 14:37:51

+0

那麼,無論哪種方式(2)絕對是真的,即使是多餘的,所以答案是(2)或(1)和(2)。 – 2010-05-28 14:38:46

+0

你說「派生類永遠不能訪問其基類的私有成員,無論它們如何繼承。」如果繼承是公開的,並且所有的方法都是在被欺騙的類中公開的。那麼,爲什麼它們不能被派生類中的對象訪問呢? – xbonez 2010-05-28 14:39:39

3

唯一正確的答案,我看到的是2,但不從Student取決於是否GraduateStudent繼承私下或公開。

私有繼承意味着它是私有知識GraduateStudentStudentGraduateStudent所以只有朋友和GraduateStudent會員可以的static_castGraduateStudent&Student&GraduateStudent*Student*,訪問公共或受保護的成員變量Student,並呼籲公衆或受保護的成員函數Student

參見:http://www.parashift.com/c++-faq-lite/private-inheritance.html

3
1. GraduateStudent objects may not use methods of Student. 

事實並非如此,所有GraduateStudent對象可以使用學生的任何公共或受保護的成員(顯然私有成員在這裏除外)內部。另外,任何使用這些對象的外部人員都無法訪問對象的基本Student類,因此對基類的訪問必須發生在GraduateStudent方法的上下文中。

2. GraduateStudent does not have access to private objects of Student. 

3. No method of GraduateStudent may call a method of Student. 

事實並非如此

4. Only const methods of GraduateStudent can call methods of Student. 

不,沒有在具有基類比非const成員更多的訪問將有const的成員所作的區分。

1

第一:繼承訪問符不修改DerivedBase交互的方式,它改變,就好像它是一個Base世界能治療Derived對象的方式。

考慮:

struct A{}; 
struct B: xxxx A 
{ 
    friend void friendly(); 
}; 
struct C: B {}; 

void outsider(); 

一個非常簡單的表格:我總結了其中A區域可以由不同的演員進行訪問。

xxxx   public  protected  private 

B   pub/prot pub/prot  pub/prot 

friendly  pub/prot pub/prot  pub/prot * 

C   pub/prot pub/prot  -- 

outsider  pub   --    -- 

注意:(*):朋友擁有與對象本身相同的權利,並不意外。

一個簡單的經驗法則是考慮如果繼承訪問說明符更寬鬆,則會覆蓋基類的訪問說明符。

由於沒有什麼比public鬆動,它不會改變任何東西。protected表示Basepublic部分變爲protected,而private表示publicprotected部分變爲private