I has this code:
struct A {
virtual void f() {}
};
struct B: A {
private:
void f() override {}
};
...
B b;
A& a = b;
a.f();
And ofcourse it will call f()
from B
cause private is checked on the compilation time but choosing virtual function version are in the runtime. Can I forbid f()
calling in this case?
No. As you call f()
on an A
reference, the access rules are checked on A
. You can't expect the compiler to check the rules for B
, because it does not necessarily know that a
is of type B
.
From cppreference:
Access rules for the names of virtual functions are checked at the call point using the type of the expression used to denote the object for which the member function is called. The access of the final overrider is ignored:
struct B { virtual int f(); }; // f is public in B
class D : public B { private: int f(); }; // f is private in D
void f() {
D d;
B& b = d;
b.f(); // OK: B::f is public, D::f is invoked even though it's private
d.f(); // error: D::f is private
}
Your code should not rely on this though. In my opinion, access specifiers for a given method should be consistent across the class hierarchy.