Поскольку задача Special_Task * является нормальной (указателем) переменной, я не понимаю, почему она считается rvalue?
Любое lvalue может быть преобразовано в rvalue посредством неявного преобразования. task
- это значение lvalue, потому что это «имя переменной ... в области видимости» (см. cppreference on value categories), и оно преобразуется в rvalue в вашем примере.
Но вся вещь lvalue/rvalue в основном является красной селедкой в этом случае. Проблема заключается в том, что вы пытаетесь присвоить указатель одного типа к опорному указателю другого типа, как сообщение об ошибке говорит:
недействительна инициализация неконстантного ссылки типа «Task * &» от RValue типа «Специальные и подчеркивание; Задача *».
(как в сторону, я бы хотел, чтобы точно знать, какой компилятор/код дал вам это сообщение Все версии GCC, что я пытался дать вместо : Неверная инициализация неконстантной ссылки типа «Задача» & 'из rvalue типа «Задача *»).
Несмотря на то, что Special_Task
является производным типом Task
, вы не можете сделать этого. Их соответствующие типы указателей не являются подтипами; a Special_Task *
не является Task *
, и поэтому Task *&
-переменная не может быть назначена Special_Task *
. (Некоторая путаница может возникнуть из-за того, что Special_Task *
может быть неявно преобразован в Task *
, однако важно отметить, что в этом случае результирующий указатель представляет собой rvalue, а не lvalue, что объясняет последнее сообщение об ошибке).
Для того, чтобы проиллюстрировать, почему вы не можете назначить Special_Task *
к Task *&
переменной, рассмотрим следующий пример:
// 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
Приведенный выше пример показывает, почему не может назначить Special_Task *
к Task *&
переменной напрямую. Из-за этого в вашем коде Special_Task *
неявно преобразуется в Task *
и становится rvalue, который также не может быть присвоен неконстантной ссылке. В примере также показано, почему ссылка const
будет в порядке: это предотвратит назначение, которое вызывает p
, чтобы указать на объект неправильного типа.
Вернуться к вашей проблеме: видя, как нет необходимости task
в Manager
быть ссылка, простое исправление изменить свое заявление на простой указатель:
Task* task;
И изменить конструктор:
Manager(Task* _task);
альтернативное решение, хотя не один я рекомендовал бы, должен был бы изменить тип к const
ссылке:
Task * const & task;
Manager(Task* const & _task);
Да, и еще одна вещь:
Special_Manager::Special_Manager() : Manager(task), task (0)
Это проходит неинициализированную значение task
к Manager
конструктора и затем инициализирует task
в 0. Вместо этого вы должны написать:
Special_Manager::Special_Manager() : Manager(0), task (0)
Потому что это не значение lvalue, потому что вы не можете назначать ссылки. – EJP
Что такое 'Special_Manager();' внутри класса 'Manager_Special' ??? –
Это Конструктор. Я исправил ошибку ввода в имени класса. – nubert