I lately discovered this short article on IBM site. Below may be the sample code

#include "iostream"

class B {
  virtual void f()
    std::cout<<"\n In class B";

class D : public B {
    int i;

  void f()
  std::cout<<"\n In class D i = "<<i;
    D(int i_num):i(i_num)

int main() {
  D dobj(10);
  B* bptr = &dobj;
  D* dptr = &dobj;

  // valid, virtual B::f() is public,
  // D::f() is called

  // error, D::f() is private

We can now call private purpose of D.I needed to understand does not this break C++ encapsulation ?

P.S. : Go to Virtual function access section in Virtual function. I don't know why I'm not getting exact link after i do paste.

The phone call bptr->f() is examined at run time with respect to the kind of objected pointed by bptr. At compile time the compile sees the bptr->f() call as call to B::f() and also, since B::f() is public the compiler does not report only error. It is simply at runtime that actual function call D::f() is examined.

This does not break the Encapsulation principle this can be a feature of C++ known as Run-time Polymorphism or Dynamic Polymorphism

You can't directly call dptr->f() because D::f() is declared under Private Access specifier and also you cannot access independently declared people from outdoors the course.

It's by design.

B::f is public. User access of f using a pointer to B is permitted. Since f is virtual, the phone call could be sent to derived classes' f.

But D::f is private, you cannot access f using a pointer do D.

Access-specifiers are compile-time construct, and thus, the compiler picks up any breach of access-rules at compile-time (clearly) in line with the static kind of the item (or pointer). Such breach can't be detected at runtime.

So bptr->f() works, since the compiler understands that the static kind of bptr is B with a public function f() defined, therefore the expression bptr->f() passes the compiler's test. Hence it really works.

But dptr->f() does not work, because the static kind of dptr is D with a private function f(), hence the code wouldn't even compile!

Now whether or not this breaks encapsulation or otherwise, is an extremely subjective question and can receive subjective solutions. It entirely is dependent how one defines it and also the arguments directly flows from this. There's nobody universal definition. My own opinion is, when the language enables it, then (it might signify) based on the C++ community, it does not break encapsulation, or maybe it will, then C++ enables it in order to achieve something very nobel (which otherwise is not possible). Otherwise, I'd say its at this time another misfeature of C++ similar to the following:

Default argument in the middle of parameter list?