The C++ compiler offers only protection from mistakes, not from abuse. For example, we may access the private base class by employing casts, as illustrated in slide 2-priv.
class A {
  public:
  A() { s = "XAX"; }
  void print() { cout << s; }
  private:
  char* s;
  };
  
  class B : private A {   }
  

slide: Casting to private base classes

In slide 2-priv we have defined a class A, and a class B that privately inherits from A. As illustrated in the program fragment
  A* a = new B; 
error

A* b = (A*) new B;
accepted

b->print();
XAX

we can access the B part of A by using a cast. However, we can also gain access by completely bypassing the public interface of a class, as illustrated by the fragment below
  char* p = (char*) b;
  while( *p != 'X' ) p++;
  cout << p << endl; 
XAX

The trick is to cast the object pointer to an array of char, which allows us to inspect each byte of the object. Casting is the most dangerous feature offered by C and C++. It allows programmers to circumvent the type system in completely arbitrary ways.