2015-01-15 57 views
1

我得到了一個練習,它應該適用於不同類別和不同類別之間的關係。撫摸動物園C++ /繼承類/子類

爲不同的類工作的函數應該爲抽象的基類定義,然後在對象上使用,該類是基類的子類。

在本練習中,我應該展示分離到接口和實現的優勢。

我應該想象一個包含許多不同動物的動物園。這些動物應分爲哺乳動物,鳥類或魚類。

  • 遊客應該可以喂一些動物(羊,鵝,金魚)
  • 而其他不能喂(熊,鯊魚)
  • 遊客還應該能夠寵物一些動物像山羊,而其他如熊,鳥和魚不能寵物
  • 一些動物應該有特點的聲音 - 魚都沉默
  • 也是寵物應該有一個綽號(他們中的每個人)

我應該實現類/子類,所以我能夠使用

void feed (Animal& Animal) 
void pet (mammal& mammal) 
void noise (mammal& mammal) 
void noise (bird& bird) 

我應該有10只不同的動物 - 使用的功能之一與每個類型(哺乳動物,鳥類,魚類)至少2 (無效飼料等)的動物應該問,如果需要的操作是可能的,然後給後面的答案是這樣的:

「的山羊比利可喂」

「熊布魯諾不喜歡待寵物「

「鵝herta夸克」

動物的特點適用於他們的整個物種(哺乳動物,鳥類,魚只是特定的動物),因此他們是獨立於實例(所有山羊都可以餵食 - 不只是比利) 關鍵字「靜態」可用於設置類變量 「static const bool feedable =;」 然後該變量將不再被應用於每個單個實例,而且它變得確定爲 該特徵適用於每種類型的動物。

使用抽象的基本類和唯一的虛擬方法。每動物/類型應使用其特定的變量和方法 它需要工作(應該有魚沒有布爾petable)

在端部也應繪製的圖,其示出了在樹結構的繼承

對不起我的英語很糟糕,但我有沒有人問 - 所以我試圖解釋它一樣好,我可以

這是我走到這一步:

動物園。^ h

#include <iostream> 
    #include <cstring> 

    using namespace std; 

    // CAnimal abstract class 

    class CAnimal { 

     public: 
      CAnimal() { strcpy(m_name, ""); } 
      virtual ~CTier() { } 
      void setName(char *name) { strcpy(m_name, name);  } 
      virtual void introduce() { cout << "Hello, my name is " <<m_name <<end1; } 
      virtual CAnimal* create(char *) = 0; // pure virtual method 

     private: 
      char m_name[50]; 
      }; 

    // CMammal 

    class CSMammal : public CAnimal { 
     public: 
      CMammal() { } 
      virtual ~CMammal() { } 
      virtual void introduce() { 
       CAnimal::introduce(); 
       cout <<"I am a mammal"<<end1; 

      } 
    }; 

    // CFish 

    class CFish : public CAnimal { 
     public: 
      CFish() { } 
      virtual ~CFish() { } 
      virtual void introduce() { 
       CTier::introduce(); 
       cout << "I am a Fish" <<end1; 

      } 
    }; 

    // CBird 

    class CBird : public CAnimal { 
     public: 
      CBird(){ } 
      virtual ~CBird() { } 
      virtual void introduce() { 
       CTier::introduce(); 
       cout << "I am a Bird" <<end1; 

      } 
    }; 

    // Tierart - legt eine Klasse an, welche von Vogel, Fisch oder Säugetier abgeleitet ist. Der Konstruktor legt die individuellen Namen fest. 

    #define ANIMALTYPE(cname,parentclass,whoami) 
     class name : public parentclass 
     { 
      public: 
       cname(char *name) { CTier::setName(name); } 
       /* Default-Konstruktor für Kreirrepresäntant */ 
       cname() { } 
       void introduce() { 
        parentclass::introduce(); 
        cout << "Ich bin " << whoami <<end1; 

       } 
      /* Kreirfunktion: Forward Ownership! */ 
      CTier* create(char *name) { return new cname(name); } 

     }; 

,這是我zoo.cpp

#include <stdlib.h> 
    #include <time.h> 
    #include "zoo.h" 


    // giving names 
    char *namen[] = { "Mehmet", "Aykut", "Dumbo", "Helga", "Henni", 
    "KQLY", "Pasha", "Huan", "Emilio", "Blume" }; 
    const int namZahl = sizeof(namen)/sizeof(*namen); 

    // Tierarten (Klassen anlegen) 
    SPEZIES(CGoat, CMammal, "a Goat") 
    SPEZIES(CPenguin, CBird, "a Penguin") 
    SPEZIES(CGoldfish, CFish, "a Goldfish") 
    SPEZIES(CBaer, CMammal, "a Baer") 
    SPEZIES(CGoose, CBird, "a Goose") 
    SPEZIES(CShark, CFish, "a Shark") 
    SPEZIES(CBadge, CMammal, "a Badger") 
    SPEZIES(CSalmon, CFisch, "a Salmon") 
    SPEZIES(CBlackbird, CBird, "a Blackbird") 
    SPEZIES(CElefant, CMammal, "an Elefant") 

// main methode 

int main(void) { 

所以,現在我不知道如何實現那些其他的「空隙」,它會給我的信息,如果我能養活動物+在練習的其餘部分使用靜態命令。

+0

你應該真的考慮使用'std :: string' – Sean

回答

0

在這種情況下,更好的設計是將所有常見行爲移到基類,這將是抽象的,然後讓子類以自己的方式實現特定的行爲。對於e.g: -

MakeNoise(); 

被每個動物的支持,所以你可以很容易地包括在基類純虛函數。但是,如果考慮餵養動物MakeNoise相同的方式包含在基類中,那麼您不會得到直觀的行爲。例如: -

Feed(Item x); 

鯊魚不會被餵食。你如何翻譯它的設計。讓這個函數在Shark中拋出錯誤?

這將意味着鯊魚可以飼餵,但試圖餵它們是錯誤的。

因此,如果您只是將其從基類中移出並按照行爲類來實現,那更好。

class Feedable {}; 
class Feed1 : public Feedable {}; 

然後在需要此行爲的類中實現這些。