Не удается получить доступ к члену защищенного класса в производном классе

Ошибки:

d_start является защищенным членом группы CourseActivity
duration является защищенным участником группы CourseActivity
location является защищенным участником группы CourseActivity

class CourseActivity{

protected:
    StartTime* d_start;
    double duration;
    std::string location;

public:
    CourseActivity() = default;
    CourseActivity(const StartTime* _start, double _duration,
                   const std::string_location);
    void reschedule(StartTime* _newStart);
    void print() const;

}; 



class Lecture: public CourseActivity{
    std::string topic;
    bool deflt = false; //indicate which constructor was used.
                        //false = 1st. true = 2nd

public:
    Lecture(const StartTime* _start, double _duration,
            const std::string location, const std::string& _topic);
    Lecture(const CourseActivity& _oActivity, const std::string& topic );
    void print();
};

// ERROR
Lecture::Lecture(const CourseActivity& _oActivity, const std::string& _topic)
: CourseActivity(_oActivity.d_start,_oActivity.duration,_oActivity.location){
    topic = _topic;
    deflt = true;
}
// ERROR 

person Hazem Beshara    schedule 14.10.2013    source источник
comment
Что вызывает ошибку? Здесь нет кода, который сделал бы это.   -  person Alec Teal    schedule 14.10.2013
comment
Вы можете получить доступ к защищенным методам родителя только из объекта, который является потомком этого родителя. Здесь oActivity не является родителем вновь созданного объекта, поэтому доступ к его защищенным членам недоступен.   -  person Ashalynd    schedule 14.10.2013
comment
Или, может быть, это дубликат этого вопроса. В любом случае это дубликат.   -  person dyp    schedule 14.10.2013
comment
Спасибо, это дубликат. я извиняюсь   -  person Hazem Beshara    schedule 14.10.2013
comment
@HazemBeshara Дубликаты иногда трудно найти. Без проблем. Я все еще искал лучшее совпадение, возможно, этот.   -  person dyp    schedule 14.10.2013
comment
Есть ли другой способ обойти это, кроме использования класса друзей или изменения видимости этих атрибутов для публики?   -  person Hazem Beshara    schedule 14.10.2013
comment
@HazemBeshara Может быть делегировать копирайтеру CourseActivity? : CourseActivity(_oActivity)   -  person dyp    schedule 14.10.2013


Ответы (1)


Вы передаете экземпляр CourseActivity функции Lecture::Lecture. Несмотря на то, что CourseActivity действительно является базовым классом Lecture, вы не можете получить доступ к защищенным членам класса извне (например, _oActivity.duration), даже если объект, с которым вы работаете, имеет производный тип.

Чтобы избежать ваших конкретных проблем, вы можете создать этот конструктор в базовом классе

CourseActivity::CourseActivity(const CourseActivity &_oActivity)

и назовите его с

Lecture::Lecture(const CourseActivity& _oActivity, const std::string& _topic)
    : CourseActivity(_oActivity)

в производном классе. В базовом классе вы можете получить доступ к защищенным членам, в отличие от производного класса, где это не разрешено.

person Atle    schedule 14.10.2013
comment
экземпляр, который вы передаете, не обязательно совпадает с текущим базовым классом. Вы имеете в виду ссылку const CourseActivity&? Это даже не разрешено при передаче по значению. - person dyp; 14.10.2013
comment
Когда вы получаете доступ к _oActivity.duration, вы получаете доступ к классу CourseActivity извне, что означает, что доступ к защищенным или закрытым членам невозможен. Неважно, где это находится в коде, оно может быть даже внутри того же класса. - person Atle; 14.10.2013
comment
Код может находиться в самом классе CourseActivity; в таком случае это разрешено. Живой пример - person dyp; 14.10.2013
comment
Истинный. Разве вы (= спрашивающий) не можете просто передать весь _oActivity в конструктор CourseActivity ? - person Atle; 14.10.2013
comment
Да, я также предложил это в комментарии к ОП. Немного подумав об этом, я бы даже рекомендовал это сделать. Базовый класс отвечает за копирование, это не должно быть работой производного класса. - person dyp; 14.10.2013
comment
Я также добавил это в свой ответ. - person Atle; 14.10.2013
comment
если это не делается внутри класса того же типа и даже если объект, с которым вы работаете, имеет производный тип. И вам не нужно создавать copy-ctor, он создается автоматически в этом случае (если вам нужна другая функциональность, а не копия для членов, то вам, конечно, придется реализовать ее самостоятельно). Живой пример - person dyp; 14.10.2013
comment
Еще раз отредактировал. Будет ли ответ развиваться дальше? - person Atle; 14.10.2013
comment
@Atle Ad protected и объекты производного класса: я только что упомянул об этом как о любопытном факте;) Это не имеет значения здесь, но я, возможно, не ясно выразился. Доступ к защищенным членам зависит от типа объекта, который содержит эти члены. Вы можете получить доступ к защищенным членам объектов вашего собственного класса и производных классов (даже если эти члены были объявлены в базовом классе вашего собственного класса), но не к любому объекту базового класса. - person dyp; 14.10.2013