2017-06-28 4 views
-1

Hallo Leute haben ein Problem, dass ich nicht zugreifen kann Feld Tablica [i] -> Hilfe, in generuj Funktion sagt es, dass dieses Feld nicht in der Klasse Task vorhanden ist. Wie kann ich es erreichen?C++ kann nicht auf Feld von geerbter Klasse zugreifen

class Task 
{ 
    protected: 
    string contents; 
    int id_pyt; 
    int nr_pyt; 
}; 

class Task4Answ : public Task 
{ 
private: 
    int help; 
public: 
    Task4Answ(string contents1, int id,int nr,int help1) 
    { 
     contents=contents1; 
     id_pyt=id; 
     nr_pyt=nr; 
     help=help1; 
    } 
}; 

class TaskCollection 
{ 
    protected: 
     Task *collection[60]; 
    public: 
     friend class Generator; 
     TaskCollection() 
     { 
      collection[0] = new Task4Answ("Ile jest por roku w Polsce? \na) 1 \nb) 2 \nc) 3 \nd) 4",1,0); 
      collection[1] = new Task4Answ("Kto wygral tegoroczny Roland Garros? \na) Federer \nb) Djokovic \nc) Nadal \nd) Thiem",1,1); 
class Generator 
{ 
protected: 
    Task *tablica[10]; 
    TaskCollection T1; 
public: 
    Generator(){} 
    void Generuj() 
    { 
      if(T1.collection[x]->id_pyt==1) 
      { 
       tablica[i]=new Task4Answ("0",0,0); 
       tablica[i]->contents=T1.collection[x]->contents; 
       tablica[i]->id_pyt=T1.collection[x]->id_pyt; 
       tablica[i]->nr_pyt=T1.collection[x]->nr_pyt; 
       tablica[i]->help=T1.collection[x]->help; //here is the problem 
      } 
     } 
    } 

Oder vielleicht gibt es eine andere Lösung des Projekts jetzt tun. Danke für jede Hilfe.

+3

Der 'Task'-Typ hat kein' help'-Element. –

+0

Es sieht aus wie 'tablica' ist ein Array von' task's, aber 'help' ist in' Task4Answ' definiert. – wecsam

+1

1) 'help' existiert nicht in' Task', es existiert in 'Task4Answ'. 2) Selbst wenn dies der Fall ist, ist "Hilfe" privat, so dass Sie sowieso nicht darauf zugreifen könnten.Wahrscheinlich möchten Sie 'help' eine Funktion machen:'/* In Aufgabe */virtual int getHelp() = 0; ','/* In Aufgabe4Answ */int getHelp überschreiben {return help; } ' – 0x5453

Antwort

2

Das Problem ist in dieser Zeile:

Obwohl Sie den Task4Answ Konstruktor aufgerufen haben, können Sie zuweisen auch die Speicheradresse durch new an einen Task Zeiger zurückgegeben. Effektiv haben Sie den Zeiger Task4Answ auf einen Zeiger Task geworfen. In den folgenden Zeilen sieht C++ nur tablica[i] als Verweis auf einen Zeiger Task. Sie müssen sich ändern:

protected: 
    Task *tablica[10]; 
    TaskCollection T1; 

... dazu:

protected: 
    Task4Answ *tablica[10]; // Task was changed to Task4Answ 
    TaskCollection T1; 

Das sollte C++ erlauben tablica als ein Array von Task4Answ Zeiger statt Task Zeiger zu sehen.

Edit: es sieht aus wie help ist auch privat. Sie müssen help in die Öffentlichkeit ändern oder TaskCollection::TaskCollection() als Freund hinzufügen. Andernfalls können Sie in C++ weder help abrufen noch festlegen.

Edit: das OP hinzugefügt, dass tablica[i] Instanzen anderer Klassen enthalten kann, die von Task erben. In diesem Fall Sie so etwas tun könnte:

void Generuj() 
{ 
     if(T1.collection[x]->id_pyt==1) 
     { 
      Task4Answ* newTask = new Task4Answ("0",0,0); 
      newTask->contents=T1.collection[x]->contents; 
      newTask->id_pyt=T1.collection[x]->id_pyt; 
      newTask->nr_pyt=T1.collection[x]->nr_pyt; 
      newTask->help=T1.collection[x]->help; // You will still have to change this from being private. 
      tablica[i] = newTask; 
     } 
    } 
} 

Später, um help zugreifen zu können, müssen Sie irgendeine Art von Art und Weise der Überprüfung, ob tablica[i] ist ein Task4Answ und nicht eine Instanz eines anderen implementieren Klasse, die von Task erbt, möglicherweise durch Implementieren einer Methode in Task mit dem Namen IsTask4Answ, die false in Task zurückgibt, aber überschrieben wird, um True in Task4Answ zurückzugeben. Sie können dann den Zeiger zurück auf Task4Answ mit etwas wie dem Operator static_cast werfen. Mit anderen Worten:

// Add these functions to the class definitions: 
virtual bool Task::IsTask4Answ() const { 
    return false; 
} 
bool Task4Answ::IsTask4Answ() const override { 
    return true; 
} 
// Later, you can do this: 
if(tablica[i].IsTask4Answ()){ 
    Task4Answ* t = static_cast<Task4Answ*>(tablica[i]); 
    t->help; // Again, you'll have to change this from being private. 
} 

Obwohl ich vorschlagen, eine andere Datenstruktur, herauszufinden, wo Sie brauchen kein Casting zu tun, dies ermöglicht es Ihnen help zuzugreifen.

Beachten Sie das Schlüsselwort virtual in der ersten obigen Funktion; Dadurch kann die Funktion dynamisch gebunden werden. Das bedeutet, dass der Code prüft, ob er zur Laufzeit statt zur Kompilierzeit Task::IsTask4Answ() oder Task4Answ::IsTask4Answ() aufrufen soll.

+0

Die Sache ist, dass ich nicht den ganzen Code in Thema geschrieben habe, weil es 4 Klassen gibt, die von Aufgabe erben, sie haben den gleichen Inhalt. Und ich muss ein Array von Objekten dieser 4 Klassen erstellen. –

+0

@DarekD Ah, das ändert die Dinge. Ich habe meine Antwort bearbeitet, um dieses Gebiet abzudecken. Wenn es möglich ist, Ihre Datenstrukturen so zu verbessern, dass sie nicht umgewandelt werden müssen, ist das normalerweise einfacher zu lesen und zu folgen. – wecsam

+0

Vielen Dank, Bruder, jetzt sehe ich meine Fehler. Ändere einige Datenstrukturen, um diese Castings nicht zu machen. Nochmals vielen Dank! –

Verwandte Themen