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().
}