2016-06-21 12 views
-4

Hier zuzugreifen, ist eine abstrakte Klasse, die ich schrieb:Wie ein Datenelement eines Vektors voller abgeleiteten Klassen

class Month 
    { 
    public: 
     //factory method 
     static Month* choose_month(int choice); //static function 
     virtual void birthstone() = 0;   //virtual function 
     virtual void month() = 0;    //virtual function 
     virtual ~Month() 
     { 
      std::cout << "Deleting the virtual destructor" << std::endl; 
     }; 
    }; 

    Month* Month::choose_month(int choice) 
    { 
    switch (choice) 
    { 
     case '1': 
      return new January; 
      break; 
     case '2': 
      return new February; 
      break; 
     //these cases go all the way to December 
     default: 
      break; 
     } 
    } 

Dann Klassen Ich schaffe zwölf abgeleitet, eine für jeden Monat des Jahres. Ich werde nur zwei der Klassen der Einfachheit halber sind:

class January : public Month 
{ 
public: 
    void birthstone() 
    { 
     std::cout << "Garnet" << std::endl; 
    } 

    void month() 
    { 
     std::cout << "January" << std::endl; 
    } 

    //destructor 
    ~January() 
    { 
     std::cout << "Deleting the object" << std::endl; 
    } 
}; 

class February : public Month 
{ 
public: 
    void birthstone() 
    { 
     std::cout << "Amethyst" << std::endl; 
    } 

    void month() 
    { 
     std::cout << "February" << std::endl; 
    } 

    //destructor 
    ~February() 
    { 
     std::cout << "Deleting the object" << std::endl; 
    } 
}; 

In meiner Hauptfunktion ich einen Zufallszahlengenerator auf die Auswahl einer abgeleiteten Klasse zu verwenden, so dass ich die Daten in ihren Mitgliedsfunktionen zugreifen können:

std::vector<Month*> stone; 

    std::srand(static_cast<unsigned>(time(0))); // Seed the random generator 

    //for-loop 
    for (int i = 0; i < 6; i++) 
    { 
     stone.push_back(Month::choose_month(random(12))); 
    } 

Das Problem tritt auf, wenn ich versuche, auf eine Mitgliedsfunktion einer Klasse zuzugreifen, die in meinem Vektor gespeichert ist. Ich halte eine Zugriffsverletzung Fehler bekommen:

//displaying the elements inside the container 
    for (std::vector<Month*>::iterator iter = stone.begin(); iter != stone.end(); iter++) 
    { 
     (*iter)->birthstone(); 
    } 

Ich kann nicht wirklich sehen, wo der Fehler ist, und frage mich, ob jemand bitte darauf hinweisen könnte, was falsch gehen? Vielen Dank.

+4

Ihre 'choice_month'-Funktion hat ein undefiniertes Verhalten, da sie nicht-void-Rückgabetyp hat und keine' return'-Anweisung für jeden Pfad hat. –

+3

Sie haben triviale Fehler, die vom Compiler abgefangen werden, wenn Sie die Warnstufe hochdrehen. – juanchopanza

+1

Sie schalten Zeichen, nicht ganze Zahlen um. – tkausl

Antwort

1

case '1' tut nicht, was Sie erwarten. '1' ist nicht 1, es ist ein Char mit Integralwert 49 (ASCII-Code). Aber random(12) wird eine int zwischen 0 und 11 zurückgeben. Es bedeutet, dass für die switch Anweisung in Month::choose_month() der default Fall immer ausgeführt wird.

Ändern Sie die case Anweisungen zu case 1: und case 2: und so weiter. (Könnte das von case 0: bis case 11:?) Wenn Sie erwarten, dass es eine char ist, ändern Sie den Typ des Parameters und ändern Sie den Code, der es auch aufruft.

Und die default Anweisung gibt nichts zurück. Sie sollten bestätigen, dass für diesen Fall ein gültiger Wert zurückgegeben wird, oder das Design darüber erneut prüfen (Hinzufügen oder Auslösen einer Ausnahme für diesen Fall oder das Beseitigen des Falls).

BTW: random ist nicht C++ Standard-Einrichtungen. Sie könnten std::rand oder C++11's random number generation facilities verwenden.