2017-04-12 89 views
1

我是C++面向對象編程的初學者。我正在學習「抽象類」裏的示例代碼:抽象類的需求是什麼?爲什麼通過其基類訪問派生類方法?在C++中

#include <iostream> 
using namespace std; 

class Enemy { 
    public: 
     virtual void attack() = 0; 
}; 

class Ninja: public Enemy { 
    public: 
     void attack() { 
      cout << "Ninja!"<<endl; 
     } 
}; 

class Monster: public Enemy { 
    public: 
     void attack() { 
      cout << "Monster!"<<endl; 
     } 
}; 


int main() 
{ 
    Ninja n; 
    Monster m; 
    Enemy *e1 = &n; 
    Enemy *e2 = &m; 

    e1->attack(); 
    e2->attack(); 

    return 0; 
} 

我想明白的是,爲什麼我就不能使用派生類的對象直接訪問派生類成員「」運營商(它的工作原理,但不建議爲什麼?)。

像這樣:

int main() 
{ 
    Ninja n; 
    Monster m; 
    Enemy *e1 = &n; 
    Enemy *e2 = &m; 

    //e1->attack(); 
    //e2->attack(); 
    n.attack(); 
    m.attack(); 

    return 0; 
} 

我知道會有我們需要通過基類訪問派生類的成員的情況(我認爲這是通常使用的所有程序員)但我不知道這種情況的實際實現(爲什麼我們不能直接進行,爲什麼要通過基類的指針?)。

如果有人能澄清我的疑問,我會很高興。

+0

的[爲什麼我們需要在C++抽象類?]可能的複製(http://stackoverflow.com/questions/14189438/why-do-we-need-abstract-classes-in-c) –

+0

你需要一個更深的例子。假設你有對敵人執行任務的功能。你不想一遍又一遍地寫一個'Ninja',一個給''Monster',一個給'Unicron'等等。 – user4581301

+0

@AndyThomas ...給我一些時間。我會理解這個概念,如果它們看起來一樣,我會刪除我的問題。謝謝。 – 14yearoldprogrammer

回答

4

一羣敵人(std::vector<Enemy*>)可以有忍者和怪物。一個忍者的集合只能包含忍者,而一羣怪物只能包含怪物。

抽象基類爲子類實現提供了一個通用接口,但抽象基類的實例沒有實際意義(否則你不會使基類抽象)。

+1

請注意,您也可以使用自己的自定義行爲在路上實現更多類型的敵人,而無需更改使用普通敵人界面編寫的任何內容。 –

0

其餘的已經涵蓋了很好的購買其他答案,但「爲什麼是一個指針?」已被忽略。

每個子類有不同的內容和可能不同的大小。如果沒有參考,程序將不得不知道分配存儲的確切大小。規定所有的子類都是相同的大小是一個非起動器,因爲它在C++的意識形態中飛過,只是爲了支付你使用的東西,並且需要修改以前編譯的代碼(一個新模塊增加了一個新的子類,所有現有的模塊也必須改變)。此外,沒有合理的方法讓基類知道其子類的細節(以及許多原因,爲什麼它不應該),這包括知道大小。

作爲參考,沒有人關心大小或實現細節。該對象是一些未知大小的匿名內存塊,如果對象是多態的,它包含自己的訪問規則和指令(這是probably a "v-table",但只要結果符合標準,C++不關心使用了什麼voodoo)。

相關問題