I might be very well just tired or too long far from C++ but this one really surprised me today:
#include <iostream>
class Interface
{
public:
virtual int aa() const = 0;
virtual int bb() const = 0;
};
class Usage : public Inter开发者_高级运维face
{
private:
virtual int aa() const
{
int a = 10 * 10;
return a;
}
virtual int bb() const
{
int b = 20 * 20;
return b;
}
};
int main(int argc, char* argv[])
{
Interface* i = new Usage();
std::cout << i->bb() << std::endl;
return 0;
}
I'd expect compiler and/or linker would complain about either bad function signature or at least about missing implementation. Considering this is working and ok, what is the meaning of public/protected/private modifiers when it's hidden by the top class declaration?
How does this rule call in C++ ?
This is specified in paragraph 11.6.1 of the standard:
The access rules (clause 11) for a virtual function are determined by its declaration and are not affected by the rules for a function that later overrides it. [Example - basically same as yours] Access is 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 member function in the class in which it was defined is in general not known.
Interface* i = new Usage();
std::cout << i->bb() << std::endl;
This is working because the function name is resolved based on the static
type of the object.
Here the object is i
whose static
type is Interface*
which has a public
function name bb()
. Hence, the compiler doesn't see any problem, as the requirement to call a member function meets it.
Also note that accessibilities (public
, private
and protected
) are compile-time constructs. At runtime, there is no such thing. Compiler can detect any violation of rules related to accessibility at compile time only. It cannot know what happens at runtime.
So even if i
points to an object whose type is Usage
which has defined bb()
in the private
section, the compiler is fine with it, as noted before the static
type of i
is still Interface*
which has a public
function bb()
. The compiler doens't bother with the dynamic type of object and how it overrides the function, because it cannot, precisely for the reason that its dynamic; its determined at runtime.
private
means you can't inherit from it. protected
or public
you can inherit from but there is nothing stopping you limiting the visibility to a lower level (i.e. public
to protected
or private
; or protected
to private
) in your top class.
精彩评论