Предположите, что у Вас есть класс, который определяет виртуальные методы с общественностью спецификатора доступа. Можно ли изменить спецификатор доступа на переопределенных методах? Я принимаю нет. Поиск объяснения.
Да, можно, но "не грок".
Взгляните на Переопределение общедоступных виртуальных функций частными функциями в C ++
Ответ: вроде как. Вы можете изменить доступ только к членам, к которым имеет доступ производный класс. Тип наследования не имеет значения - он контролирует только доступ по умолчанию для унаследованных членов (до определенной точки, следуя другим правилам).
Итак, вы можете сделать защищенные члены базового класса открытыми или закрытыми; или публичные члены базы, защищенные или частные. Однако вы не можете сделать частных участников базы общедоступными или защищенными.
Пример:
class Foo
{
protected:
void protected_member();
private:
void private_member();
public:
void public_member();
};
class Bar : private Foo
{
public:
using Foo::protected_member;
using Foo::private_member;
using Foo::public_member;
};
int main(int, const char**)
{
Bar bar;
return 0;
}
Приведенный выше код вызывает следующую ошибку в g ++ 4.1.2:
main.C: 7: error: 'void Foo :: private_member ()' is private
main.C: 14: ошибка: в этом контексте
Кроме того, переопределение не имеет ничего общего с изменением доступа к методу. Вы можете переопределить виртуальный частный метод, вы просто не можете вызвать его из производного класса.
Вы определенно можете. Но в этом нет смысла. Если это публичное наследование, то вы всегда можете привести объект к его базе. Если это частное наследование, все базовые методы по умолчанию уже являются частными. В случае защищенного наследования вы можете сделать базовый метод закрытым, чтобы предотвратить его вызов возможными производными классами, но я действительно не понимаю, зачем он может понадобиться.
Да, вы можете, и на самом деле вам даже не нужно переопределять или использовать что-либо виртуальное.
class ABC {
public: // or this may be protected, no difference
void woof();
void moo();
};
class D : private ABC { // now woof and moo are private
public:
using ABC::woof; // using declaration to make woof public again
ABC::moo; // access declaration (deprecated) does the same
};
То же самое работает, если они виртуальные. Или, как отмечали другие, поиск виртуальной функции игнорирует доступ, указанный реализующим классом; любой класс, к которому вы можете привести, может предоставить доступ во время компиляции.
С другой стороны, без специальных объявлений в D
, общедоступный
интерфейс ABC
действительно был бы недоступен через D
потому что вы не сможете выполнить апкастинг до ABC
. И если бы woof
и moo
были виртуальными
, вам нужно сделать переопределения частными
, чтобы скрыть их. Возможно, это лучший ответ на вопрос.