2
votes

I have a Base class pointer pointing to derived class object. The method foo() is public in base class but private in derived class. Base class foo() is virtual. So when i call foo() from Base class pointer, Vptr Table has the address of derived class foo(), BUT its private in Derived class ...so how is it getting called.??

I understand Run time polymorphism and i also understand that the Access specifiers work for compile time and Virtual concept works at run time. So there shall be No Compiler error.

My question is : Is this is a loop hole through which we can call private methods of Derived class ? or Its expected to behave this way. Any good Explanation for this behavior.

Thanks a lot in advance.

CODE :

class A
{
public:
    virtual void foo()
    {
        std::cout << "In A";
    }
};


class B:public A
{
private:
    void foo()
    {
       std::cout << "In B ??? Its Private Method :-( ";
    }
};

int main()
{
    A* ptr = new B();
    ptr->foo();
    return 0;
}
2

2 Answers

7
votes

It's private method, but since it's virtual - it can be called.

n3690 11.5/1

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.

Why this? Since

n3690 11.5/2

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 (B* in the example above). The access of the member function in the class in which it was defined (D in the example above) is in general not known.

3
votes

Access level is a compile-time concept. The runtime doesn't know if a method was declared private or public. Those are there for your convenience.

This is actually a good coding standard - a virtual method should be ideally public in the base class and private or protected in derived classes. This will force the caller to use the interfaces rather than the actual types (of course, this isn't always practical, but a good thing to take into account).

The concrete type is abstracted away in your case, as it should be. The base method is declared public and you're calling it through a pointer to a base, so it's allowed.