То, что вы переопределяете, не влияет на доступ. Таким образом, вы можете создать открытое переопределение приватно унаследованной функции точно так же, как вы создаете закрытое переопределение публично унаследованной функции.
Открытое переопределение приватно унаследованной функции, очевидно, должно вызывать реальную функцию, и она должна быть встроенной, поэтому компилятор ее оптимизирует.
Что, если A является чисто абстрактным? это имеет значение?
Единственное отличие, которое он делает, состоит в следующем, то есть как они могут (или не могут) использоваться:
A *pa = new B();
pa->my_func2(10); //calls B::my_func2() even though its private!
B *pb = new B();
pb->my_func2(10); //compilation error - trying to access private function
Спецификаторы доступа являются конструкцией времени компиляции, и поэтому компилятор обнаруживает любое нарушение правил доступа во время компиляции (очевидно) на основе статического типа объекта (или указателя) . Такое нарушение не может быть обнаружено во время выполнения.
Таким образом, pa->my_func2()
работает, потому что компилятор видит, что статический тип pa
равен A*
, для которого определена открытая функция my_func2()
, поэтому выражение pa->my_func2()
проходит тест компилятора. Следовательно, это работает.
Но pb->my_func2()
не работает, поскольку статическим типом pb
является B*
, который имеет закрытую функцию my_func2()
, поэтому код даже не скомпилируется!