#include <iostream>

using namespace std;


class myBase
{
public:
  myBase() {basevalue=2;} // default constructor for base class
  void show() {cout << basevalue << endl;}
  void showall() { protectedshow(); privateshow();}
protected:
  void protectedshow() {cout << "Protected: " << basevalue << endl;}
private:
  void privateshow() {cout << "Private: " << basevalue << endl;}
  long basevalue;
};


class myDerived : public myBase
{
public:
  myDerived() { derivedvalue=3; } // default constructor for derived class
  void laatzien() { cout << derivedvalue << endl; }
  void use_protected() { protectedshow(); }

  void use_private()
  {
    cout << "Doesn't do much really...\n";
    //privateshow(); // mag niet want is private base class functie
  }
private:
  long derivedvalue;
};


int main()
{
myDerived md; // default constructor uit derived EN base worden aangeroepen
myBase mb;

  /*
   * Een object van derived class mag zelf (met functies uit het derived
   * class gedeelte) een protected functie uit het base class gedeelte aanroepen.
   * Deze gedraagt zich namelijk alsof het een private functie is: beschikbaar
   * voor het object zelf, maar niet van buiten aan te roepen.
   *
   * Dit in tegenstelling tot een functie uit het private base class deel.
   * Die mag alleen door functies uit het base class deel gebruikt worden.
   */
  cout << "\nCall protected use_protected() from derived class part\n";
  md.use_protected(); // roep protected functie uit derived-deel aan

  cout << "\nCall use_private() from derived class part\n";
  md.use_private(); // weinig nuttig in dit geval

  /*
   * Een object van derived class mag via functies uit het base class deel
   * wel protected en private functies uit het base class deel aanroepen,
   * maar niet direct
   */
  cout << "\nCall protected and private functions from base class part\n";
  md.showall();

  /*
   * van 'buiten' aanroepen van protected en private functies mag niet
   */
  // md.protectedshow(); // mag niet want is protected in base gedeelte
  // md.privateshow(); // mag niet want is private in base gedeelte

  /*
   * Tot slot: protected functies in een object van type base class mag je
   *   niet van buiten af aanroepen. Private functies natuurlijk ook niet.
   */
  // mb.protectedshow(); // mag niet want is protected in base class
} // main()

