Частный член функции, вызываемый вне класса
В приведенном ниже примере, почему вызов B::f()
, даже если он является закрытым?
Я знаю этот факт:
Доступ проверяется в точке вызова с использованием типа выражения, используемого для обозначения объекта, для которого вызывается функция-член.
#include <iostream>
class A {
public:
virtual void f() { std::cout << "virtual_function"; }
};
class B : public A {
private:
void f() { std::cout << "private_function"; }
};
void C(A &g) { g.f(); }
int main() {
B b;
C(b);
}
Ответы
Ответ 1
Поскольку стандарт говорит так:
[C++11: 11.5/1]:
Правила доступа (раздел 11) для виртуальной функции определяются ее объявлением и не зависят от правил для функции, которая впоследствии переопределяет ее. [Пример:
class B {
public:
virtual int f();
};
class D : public B {
private:
int f();
};
void f() {
D d;
B* pb = &d;
D* pd = &d;
pb->f(); // OK: B::f() is public,
// D::f() is invoked
pd->f(); // error: D::f() is private
}
-end пример]
Пример такой же, как ваш, lol.
Ответ 2
private
функции могут переопределять виртуальные функции public
из базового класса. Доступность, по сути, полностью игнорируется при определении того, переопределяет ли функция другую, поэтому даже в
// Redundant private for clarity:
class A { private: virtual void foo(); };
class B : A { public: void foo(); };
B::foo
переопределяет A::foo
.
Ответ 3
В течение времени компиляции компилятор С++ проверяет доступность функций и методов на основе их типа. В функции C переменная g имеет тип A (проверяется во время компиляции кода), в которой метод f объявляется публичным.
Посмотрите эту ссылку