Inheritance Examples

 


/*
/* This file will be useful near the end of the quarter.
** This file contains the results of a compilation based on the first
** question of the final study guide.  The only differences are the
** shorter class names, and the addition of a member function (foo) to
** each class for illustration purposes.  Note: it makes *no* difference
** that foo is declared in the private section of each class; the results
** would be identical if the various foos were public or protected.
*/

class A {
  public:
    int a;
  protected:
    int b;
  private:
    int c;
    void foo();
};

class B : public A {
  public:
    int a;
  protected:
    int b;
  private:
    int c;
    void foo();
};

class C : protected A {
  public:
    int a;
  protected:
    int b;
  private:
    int c;
    void foo();
};

class D : private A {
  public:
    int a;
  protected:
    int b;
  private:
    int c;
    void foo();
};

void A::foo() {

  B my_b;
  C my_c;
  D my_d;

  /*
  ** Objects may always access their own, explicity declared (as opposed
  ** to inherited) members.
  */
  a = 10;
  b = 10;
  c = 10;

/*
** A is the parent class of B, C, & D, which (much to my surprise) gives
** it special access to the inherited fields of those classes.  Note below
** that this function is allowed to access the A::b and A::c fields, even
** though other "outsiders" cannot.  For fields declared *explicitly*
** within B, C, & D, however, A is just another "outsider" which is only
** allowed access to public fields.
*/

  my_b.A::a = 11;
  my_b.A::b = 11;
  my_b.A::c = 11;
  my_b.a = 11;
  my_b.b = 11;
/* Error: b is not accessible from A::foo(). */
  my_b.c = 11;
/* Error: c is not accessible from A::foo(). */

  my_c.A::a = 12;
  my_c.A::b = 12;
  my_c.A::c = 12;
  my_c.a = 12;
  my_c.b = 12;
/* Error: b is not accessible from A::foo(). */
  my_c.c = 12;
/* Error: c is not accessible from A::foo(). */

  my_d.A::a = 13;
  my_d.A::b = 13;
  my_d.A::c = 13;
  my_d.a = 13;
  my_d.b = 13;
/* Error: b is not accessible from A::foo(). */
  my_d.c = 13;
/* Error: c is not accessible from A::foo(). */

}

void B::foo() {

  A my_a;
  C my_c;
  D my_d;

/*
** Regardless of inheritance, objects can always access all inherited
** members that that weren't declared private by their parent.
*/
  a = 10;
  b = 10;
  c = 10;
  A::a = 10;
  A::b = 10;
  A::c = 10; /* A declared its c field to be private. */
/* Error: c is not accessible from B::foo(). */

/*
** Note that child classes may access their own inherited fields which the
** parent class declared protected (like A::b above), but not the equivalent
** field of *other* objects (like mya.b or my_c.A::b below).
*/

  my_a.a = 11;
  my_a.b = 11;
/* Error: b is not accessible from B::foo(). */
  my_a.c = 11;
/* Error: c is not accessible from B::foo(). */

  my_c.A::a = 12;
/* Error: a is not accessible from B::foo(). */
  my_c.A::b = 12;
/* Error: b is not accessible from B::foo(). */
  my_c.A::c = 12;
/* Error: c is not accessible from B::foo(). */
  my_c.a = 12;
  my_c.b = 12;
/* Error: b is not accessible from B::foo(). */
  my_c.c = 12;
/* Error: c is not accessible from B::foo(). */

  my_d.A::a = 13;
/* Error: a is not accessible from B::foo(). */
  my_d.A::b = 13;
/* Error: b is not accessible from B::foo(). */
  my_d.A::c = 13;
/* Error: c is not accessible from B::foo(). */
  my_d.a = 13;
  my_d.b = 13;
/* Error: b is not accessible from B::foo(). */
  my_d.c = 13;
/* Error: c is not accessible from B::foo(). */

}

void C::foo() {

  A my_a;
  B my_b;
  D my_d;

/*
** Results from C::foo() will be pretty much equivalent to the results
** from B::foo().  The only distinction is that, because of B's public
** inheritance of A, the A::a field of B objects is available to everyone.
** The A::a field of C and D objects, on the other hand, is inaccessible
** to "outsiders", including the member functions of "sibling" classes.
*/

  a = 10;
  b = 10;
  c = 10;
  A::a = 10;
  A::b = 10;
  A::c = 10;
/* Error: c is not accessible from C::foo(). */

  my_a.a = 11;
  my_a.b = 11;
/* Error: b is not accessible from C::foo(). */
  my_a.c = 11;
/* Error: c is not accessible from C::foo(). */

  my_b.A::a = 12;
  my_b.A::b = 12;
/* Error: b is not accessible from C::foo(). */
  my_b.A::c = 12;
/* Error: c is not accessible from C::foo(). */
  my_b.a = 12;
  my_b.b = 12;
/* Error: b is not accessible from C::foo(). */
  my_b.c = 12;
/* Error: c is not accessible from C::foo(). */

  my_d.A::a = 13;
/* Error: a is not accessible from C::foo(). */
  my_d.A::b = 13;
/* Error: b is not accessible from C::foo(). */
  my_d.A::c = 13;
/* Error: c is not accessible from C::foo(). */
  my_d.a = 13;
  my_d.b = 13;
/* Error: b is not accessible from C::foo(). */
  my_d.c = 13;
/* Error: c is not accessible from C::foo(). */

}

void D::foo() {

  A my_a;
  B my_b;
  C my_c;

/*
** Again, the results from D::foo() mimic B::foo()
*/

  a = 10;
  b = 10;
  c = 10;
  A::a = 10;
  A::b = 10;
  A::c = 10;
/* Error: c is not accessible from D::foo().

  my_a.a = 11;
  my_a.b = 11;
/* Error: b is not accessible from D::foo().
  my_a.c = 11;
/* Error: c is not accessible from D::foo().

  my_b.A::a = 13;
  my_b.A::b = 13;
/* Error: b is not accessible from D::foo().
  my_b.A::c = 13;
/* Error: c is not accessible from D::foo().
  my_b.a = 13;
  my_b.b = 13;
/* Error: b is not accessible from D::foo().
  my_b.c = 13;
/* Error: c is not accessible from D::foo().

  my_c.A::a = 12;
/* Error: a is not accessible from D::foo().
  my_c.A::b = 12;
/* Error: b is not accessible from D::foo().
  my_c.A::c = 12;
/* Error: c is not accessible from D::foo().
  my_c.a = 12;
  my_c.b = 12;
/* Error: b is not accessible from D::foo().
  my_c.c = 12;
/* Error: c is not accessible from D::foo().

}

int main() {

  A main_a;
  B main_b;
  C main_c;
  D main_d;

/*
** main() is the ultimate "outsider", so access restrictions really take
** effect here.  Note that the results for main_c and main_d are
** equivalent; the difference between protected and private inheritance
** would only be visible in further classes inherited from C and D.
*/

  main_a.a = 11;
  main_a.b = 11;
/* Error: b is not accessible from main().
  main_a.c = 11;
/* Error: c is not accessible from main().

  main_b.A::a = 13;
  main_b.A::b = 13;
/* Error: b is not accessible from main().
  main_b.A::c = 13;
/* Error: c is not accessible from main().
  main_b.a = 13;
  main_b.b = 13;
/* Error: b is not accessible from main().
  main_b.c = 13;
/* Error: c is not accessible from main().

  main_c.A::a = 12;
/* Error: a is not accessible from main().
  main_c.A::b = 12;
/* Error: b is not accessible from main().
  main_c.A::c = 12;
/* Error: c is not accessible from main().
  main_c.a = 12;
  main_c.b = 12;
/* Error: b is not accessible from main().
  main_c.c = 12;
/* Error: c is not accessible from main().

  main_d.A::a = 12;
/* Error: a is not accessible from main().
  main_d.A::b = 12;
/* Error: b is not accessible from main().
  main_d.A::c = 12;
/* Error: c is not accessible from main().
  main_d.a = 12;
  main_d.b = 12;
/* Error: b is not accessible from main().
  main_d.c = 12;
/* Error: c is not accessible from main().

}