What are the rules for accessibility when virtual functions are declared under 3 different access specifiers specified by C++(public, private, protected) What is the significance of each? Any simple code examples to explain the concept will be highly useful.
Virtual functions are just like regular functions (exception of pure virtuals) when they are used in the base class.
To summarise from the top of my head:
public functions can be accessed by anyone. private functions can be accessed only be the class and its friends protected functions are like private ones, only they can be accessed by derived classes.
Public is the interface, and private/protected functions are the internals. Also note that all the local variables (according to encapsulism) should be protected/private.
Now, when it comes to derived classes, you derive a class like this:
class A : [public | protected | private] B
{
};
Now, the public/private/protected qualifier infront of B states the least restrictive security level to inherit from the base class. This is not a "filter" for the methods and local variables in the sense that some aren't inherited, it just changes their security level to the one specified if they are less restricted (more public).
So class A : public B
will leave the inherited base members as they are while,
class A : private B
will change them all to private members.
Hope this makes sense to you and answers your question. If not, tell me!
Access specifiers apply in the same way as they would to any other name during name lookup. The fact that the function is virtual does not matter at all.
There is a common mistake which sometimes happens with respect to virtual functions.
If name lookup determines a viable function to be a virtual function, the access specifier of the virtual function is checked in the scope of the static type of the object expression used to name the function. At run time, the actual function to be called could be defined in the derived class with a completely different access specifier. This is because 'access specifiers' are a compile time phenomonon.
// Brain compiled code ahead
struct A{
virtual void f() {}
private:
virtual void g() {}
protected:
virtual void h() {}
};
struct B : A{
private:
virtual void f() {} // Allowed, but not a good habit I guess!
};
B b;
A &ra = b;
ra.f(); // name lookup of 'f' is done in 'A' and found to be public. Compilation
// succeeds and the call is dynamically bound
// At run time the actual function to be called is 'B::f' which could be private, protected etc but that does not matter