Я пробегался через некоторые демонстрационные вопросы для предстоящего теста, и этот вопрос полностью сбивает с толку меня.
Рассмотрите следующий код:
class GraduateStudent : public Student
{
...
};
Если слово "общественность" опущено, GraduateStudent
использует частное наследование, которое означает который из следующего?
GraduateStudent
объекты не могут использовать методы Student
.
GraduateStudent
не имеет доступа к частным объектам Student
.
Никакой метод GraduateStudent
может назвать метод Student
.
Только const
методы GraduateStudent
может назвать методы Student
.
Несмотря на то, что это голый вопрос, похожий на домашнее задание, я отвечу на него, потому что это ужасный вопрос. Я бы счел его вопросом с подвохом, и он не очень подходит для проверки знаний.
Ответ: 2. GraduateStudent не имеет доступа к приватным объектам Student. , за исключением того, что это не имеет никакого отношения к частному наследованию. Пункт 2 был бы верен независимо от наличия или отсутствия ключевого слова public
, поскольку производные классы никогда не имеют доступа к приватным членам своих базовых классов, независимо от способа наследования.
Частное наследование означает, по сути, две вещи (в отличие от публичного наследования):
Все публичные методы Student
становятся частными методами в GraduateStudent
. Это означает, что если, например, Student
имеет публичный метод foo()
, то GraduateStudent
имеет private метод foo()
.
Базовый класс является "недоступным", что означает, что полиморфизм не работает. Говоря простым языком, это означает, что если GraduateStudent
частным образом наследуется от Student
, то нельзя обращаться с GraduateStudent*
как с Student*
(или с GraduateStudent&
как с Student&
).
Возможно, автор вопроса также хотел, чтобы пункт 1 был правильным ответом, но он сформулирован двусмысленно. Что означает, что "GraduateStudent
объекты не могут использовать методы Student
"? Возможно, это означает, что нельзя вызывать методы, унаследованные от Student
on объектов типа GraduateStudent
, как я писал в первом пункте выше, но сам объект GraduateStudent
, внутри своих методов, может использовать методы Student
.
Например:
class Student {
public:
void foo() {};
};
class GraduateStudent : Student {
public:
void bar()
{
foo(); // Legal
}
};
int main() {
GraduateStudent g;
g.bar(); // Legal
g.foo(); // Illegal
return 0;
};
Единственный правильный ответ, который я вижу - 2, но это не зависит от того, наследует ли GraduateStudent
от Student
частным или публичным образом.
Частное наследование означает, что это частное знание о том, что GraduateStudent
является Student
, поэтому только друзья членов GraduateStudent
и GraduateStudent
могут static_cast
GraduateStudent&
в Student&
и GraduateStudent*
в Student*
, обращаться к публичным или защищенным переменным-членам Student
и вызывать публичные или защищенные функции-члены Student
.
См: http://www.parashift.com/c++-faq-lite/private-inheritance.html
Во-первых: спецификатор доступа к наследованию не изменяет способ взаимодействия Derived
с Base
, он изменяет то, как мир может обращаться с объектом Derived
, как если бы это был Base
.
Рассмотрим:
struct A{};
struct B: xxxx A
{
friend void friendly();
};
struct C: B {};
void outsider();
Очень простая таблица: Я суммирую, к каким зонам A
могут получить доступ различные субъекты.
xxxx public protected private
B pub/prot pub/prot pub/prot
friendly pub/prot pub/prot pub/prot *
C pub/prot pub/prot --
outsider pub -- --
Примечание (*): Друг имеет те же права, что и сам объект, ничего удивительного.
Простое эмпирическое правило - считать, что спецификатор доступа наследования перекрывает спецификаторы доступа базового класса, если они более свободны.
Поскольку нет ничего свободнее, чем public
, это ничего не меняет. protected
означает, что секция public
в Base
становится protected
, а private
означает, что секции public
и protected
становятся private
.
1. GraduateStudent objects may not use methods of Student.
Неправда, все объекты GraduateStudent могут использовать любые открытые или защищенные члены Student (очевидно, частные члены являются здесь исключением) внутри. Также любой посторонний, использующий эти объекты, не может получить доступ к базовому классу Student объекта, доступ к базовому классу должен происходить в контексте методов GraduateStudent.
2. GraduateStudent does not have access to private objects of Student.
Да
3. No method of GraduateStudent may call a method of Student.
Неправда
4. Only const methods of GraduateStudent can call methods of Student.
Нет, нет никакого различия между константными членами, имеющими больший доступ к базовому классу, чем неконстантные члены.