Da Special_Task * Aufgabe eine normale (Zeiger) Variable ist, sehe ich nicht, warum es als ein rvalue betrachtet wird?
Beliebiger L-Wert kann über eine implizite Konvertierung in einen R-Wert konvertiert werden. task
ist ein Lvalue, weil es "der Name einer Variablen ... im Bereich" ist (siehe cppreference on value categories) und in Ihrem Beispiel in einen rvalue konvertiert wird.
Aber das ganze lvalue/rvalue-Ding ist in diesem Fall größtenteils ein redhering. Das Problem ist, dass Sie einen Zeiger von einem Typ in einen Zeigerverweis eines anderen Typs zuweisen versuchen, wie die Fehlermeldung sagt:
ungültige Initialisierung einer nicht konstanter Referenz vom Typ ‚Aufgabe * &‘ von rvalue vom Typ ‚Sonder & Underbar, Aufgabe *‘.
(so nebenbei, ich würde gerne wissen, was genau Compiler/Code, den Sie diese Nachricht gab Alle Versionen von gcc, die ich versucht habe, geben statt : ungültige Initialisierung von nicht-const Referenz des Typs 'Task * &' aus einem Rvalue des Typs 'Task *').
Obwohl Special_Task
ist eine abgeleitete Art von Task
, können Sie dies nicht tun. Ihre jeweiligen Zeigertypen sind keine Subtypen. a Special_Task *
ist kein Task *
und daher eine Task *&
-variable kann nicht zugewiesen werden Special_Task *
. (Eine gewisse Verwirrung kann aus der Tatsache resultieren, dass Special_Task *
implizit in eine Task *
konvertiert werden kann, jedoch ist es wichtig zu beachten, dass in diesem Fall der resultierende Zeiger ein rvalue ist, kein lvalue, was die letztere Fehlermeldung erklärt).
Um zu zeigen, warum Sie nicht ein Special_Task *
zu einem Task *&
Variablen zuweisen können, sollen Sie das folgende Beispiel:
// Other_Task is a second derived class of Task:
class Other_Task : public Task { /* ... */ }
Special_Task st;
Special_Task *p = &st; // ok, p points to st
Task *& tp = p; // if it were allowed: tp references p
Other_Task ot;
tp = &ot; // now, p points to ot - which is the wrong type
Das obige Beispiel zeigt, warum nicht direkt ein Special_Task *
auf einen Task *&
Variable zuweisen kann. Aus diesem Grund wird die Special_Task *
in Ihrem Code implizit in eine Task *
konvertiert und wird zu einem rvalue, der auch nicht einer nichtkonstanten Referenz zugewiesen werden kann. Das Beispiel zeigt auch, warum eine const
Referenz in Ordnung wäre: Es würde die Zuweisung verhindern, die bewirkt, dass auf ein Objekt des falschen Typs zeigt.
Zurück zu Ihrem Problem: da gibt es keine Notwendigkeit für task
in Manager
ist eine Referenz, die einfache Lösung zu sein, ist seine Erklärung auf einen einfachen Zeiger zu ändern:
Task* task;
und ändern Sie den Konstruktor:
Manager(Task* _task);
eine alternative Lösung, wenn man nicht, dass ich empfehlen würde, wäre die Art zu einer const
Referenz zu ändern:
Task * const & task;
Manager(Task* const & _task);
Oh, und noch etwas:
Special_Manager::Special_Manager() : Manager(task), task (0)
Dieser übergibt die nicht initialisierte Wert von task
zum Manager
Konstruktor und dann initialisiert task
auf 0 Stattdessen sollten Sie schreiben:
Special_Manager::Special_Manager() : Manager(0), task (0)
Weil es kein Lvalue ist, weil Sie Referenzen nicht zuordnen können. – EJP
Was ist das 'Special_Manager();' in der Klasse 'Manager_Special' ??? –
Das ist der Konstruktor. Ich habe den Tippfehler im Klassennamen korrigiert. – nubert