C++ - доступ к защищенным / закрытым членам базового класса
Я пробую небольшой пример, чтобы практиковать концепции наследования и полиморфизма. Вот упрощенная версия моего кода:
class Shape {
protected:
int length;
int width;
public:
virtual void setLength(int l) = 0;
virtual void setWidth(int w) = 0;
};
class Rectangle : public Shape {
public:
Rectangle(int l, int w)
: length(l), width(w)
{ }
void setWidth(int w) { width = w; }
void setLength(int l) { length = l; }
};
int main() {
Rectangle r(0,0);
}
Я пытаюсь запустить вышеупомянутую программу. Однако, когда я компилирую rectangle.cc, я получаю следующую ошибку
g++ -c rectangle.cc
rectangle.cc: In constructor 'Rectangle::Rectangle(int, int)':
rectangle.cc:13:5: error: class 'Rectangle' does not have any field named 'length'
rectangle.cc:13:16: error: class 'Rectangle' does not have any field named 'width'
Насколько я понимаю, при публичном наследовании защищенные члены базового класса становятся защищенными членами производного класса и должны быть доступны как открытые члены. Разве это неверно? Кроме того, как бы код тогда нужно изменить, если длина и ширина были частными членами базового класса?
3 ответа:
Насколько я понимаю, при публичном наследовании защищенные члены базового класса становятся защищенными членами производного класса и должны быть доступны как открытые члены. Разве это неверно?
Это В основном верно. Открытые и защищенные члены базовых классов доступны в производных классах (
Для этого вам придется добавить конструктор, которому ваш конструкторpublic
наследование здесь не имеет значения - это влияет только на доступ внешних наблюдателей). Однако члены класса (любого доступа) могут быть только инициализированы в своем собственном классе. В этом случае толькоShape
может инициализироватьlength
иwidth
- неважно, что ониprotected
, то же самое было бы верно, если бы они былиpublic
илиprivate
.Rectangle
может просто делегировать права. Это работает независимо от управления доступомlength
иwidth
(пока конструкторShape
являетсяpublic
илиprotected
):struct Shape { Shape(int l, int w) : length(l), width(w) { } }; struct Rectangle { Rectangle(int l, int w) : Shape(l, w) { } };
Или, для полноты картины, вы можете просто назначить их, но определенно предпочитаю иметь
Shape
инициализировать их. Кроме того, это работает только в том случае, если рассматриваемые членыpublic
илиprotected
:Обратите внимание, что ваши функцииRectangle(int l, int w) { length = l; width = w; }
setWidth()
иsetLength()
хороши - у вас есть доступ к этим защищенным членам в функциях-членахRectangle
. Только не для инициализации.
Нет, защищенные члены базового класса не становятся защищенными членами производного класса. Защищенные члены базового класса доступны производному классу, В отличие от закрытых членов, и они остаются защищенными в пространстве имен производного класса (поэтому то же самое относится к производному классу производного класса и т. д.).
Но защищенные члены базового класса по-прежнему являются членами базового класса, и конструктор базового класса по-прежнему отвечает за построение они, а не конструктор производного класса.
Удалить деталь: длина (l), ширина (w) если вы хотите использовать длину и ширину (наследуемые) в производном классе, вы можете использовать его, просто взяв его имя, например length.. сделано... если у вас есть то же самое именованное поле 'length' в производном классе, то для использования производного класса 'length' используйте это->length...
При наследовании... публичного доступа спецификатор утверждает, что общественность от базового класса становятся публичными в производном классе защищен от базового класса становятся защищенными...
При использовании защищенный... публичный и защищенный от базового класса становятся защищенными