Частный член функции, вызываемый вне класса

В приведенном ниже примере, почему вызов 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 объявляется публичным.

Посмотрите эту ссылку