开发者

When inheriting from public interface, why it doesn't matter if the implementation is public or private?

开发者 https://www.devze.com 2023-03-16 02:56 出处:网络
I might be very well just tired or too long far from C++ but this one really surprised me today: #include <iostream>

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消