I started to write this in reply to another question on the same subject (Not Completed)
When a class derives from another (base) class, the derived class contains a
subobject of the base class (as we all know).
The Derived class can control exposure of the Base Class to outsiders - by deciding whether
the inheritance is public, protected, or private.
Using this Base Class:
1 2 3 4 5 6 7 8 9
|
class Base
{
public:
int a;
protected:
int b;
private:
int c;
};
|
//====================================================
PUBLIC INHERITANCE
class Derived :public Base{};
Looks like:
1 2 3 4 5 6
|
class Derived
{
public:
Base; //Base Object accessible to all
};
|
//=========================================================================
PROTECTED INHERITANCE
class Derived :protected Base{};
Looks like:
1 2 3 4 5
|
class Derived
{
protected Base; //Base subobject accessible to Friends of Derived and Children of Derived.
};
|
//======================================================================================
PRIVATE INHERITANCE
class Derived :private Base{};
Looks like:
1 2 3 4 5
|
class Derived
{
private:
Base; //Base subobject accesible to Friends of derived.
};
|
//========================================================================================
Note:
1. The type of inheritance has no effect on how the Derived class sees it's base class.
From within a Derived Class member function, the derived class will see Base::a as public, base:b as protected
and Base::c as private.
//======================================================================================
So considering this code (taken from a question asked in the forum):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
|
class parentFriend;
class parent
{
friend class parentFriend;
public:
void f1() {};
protected:
void f2() {};
private:
void f3() {};
};
class childpub: public parent {};
class childprot: protected parent {};
class childprv: private parent {};
class parentFriend
{
public:
void f()
{
/* which of the following 6 statements will compile? why? why not?*/
//Standard stuff - ALL OK
parent p;
p.f1();
p.f2();
p.f3();
//These three are OK because parent is a public object in childpub and accessible by anyone
//and parentfriend class has full access right to parent
childpub cpub;
cpub.f1();//OK
cpub.f2();//OK
cpub.f3(); // (1)//OK
//Here is a problem
//GCC compiler apparently does not do protected inheritance correctly
//There sholnd be no access to parent by parentfriend because parent is a protected member
//of childprot.
//You would need to be a friend of childprot, or a class derived from childprot and parentfriend
//is not either of these
childprot cprot;
cprot.f1();//OK on GCC, NOT OK on MSVC
cprot.f2(); // (2) //OK on GCC - NOT OK on MSVC
cprot.f3(); //(3) //NOT OK on GCC - NOT OK on NSVC
//NOT OK
//parent is a private member of childpriv
//You need to be a friend of childprv to get access (and parentfriend is not a friend of childpriv)
childprv cprv;
cprv.f1(); // (4) //Not OK on GCC or MSVC
cprv.f2(); // (5) //NOT OK on GCC or MSVC
cprv.f3(); // (6) //Not OK on GCC or MSVC
}
};
|
//============================================================
Note:
The inheritance level defined by the derived class can a considered a firstline of defence in trying
to access the Base class subobject. Even if it pass this security check, it does not mean that a particular
function/class would have have unlimited access to the Base class subobject - there is still
the function/class relationship with the base class to consider.
//TO be Continued=============