What is the difference between
public
,private
, andprotected
inheritance in C++?
Limiting the visibility of inheritance will make code not able to see that some class inherits another class: Implicit conversions from the derived to the base won't work, and static_cast
from the base to the derived won't work either.
Only members/friends of a class can see private inheritance, and only members/friends and derived classes can see protected inheritance.
public inheritance
IS-A inheritance. A button is-a window, and anywhere where a window is needed, a button can be passed too.
class button : public window { };
protected inheritance
Protected implemented-in-terms-of. Rarely useful. Used in boost::compressed_pair
to derive from empty classes and save memory using empty base class optimization (example below doesn't use template to keep being at the point):
struct empty_pair_impl : protected empty_class_1
{ non_empty_class_2 second; };
struct pair : private empty_pair_impl {
non_empty_class_2 &second() {
return this->second;
}
empty_class_1 &first() {
return *this; // notice we return *this!
}
};
private inheritance
Implemented-in-terms-of. The usage of the base class is only for implementing the derived class. Useful with traits and if size matters (empty traits that only contain functions will make use of the empty base class optimization). Often containment is the better solution, though. The size for strings is critical, so it's an often seen usage here
template<typename StorageModel>
struct string : private StorageModel {
public:
void realloc() {
// uses inherited function
StorageModel::realloc();
}
};
public member
Aggregate
class pair {
public:
First first;
Second second;
};
Accessors
class window {
public:
int getWidth() const;
};
protected member
Providing enhanced access for derived classes
class stack {
protected:
vector<element> c;
};
class window {
protected:
void registerClass(window_descriptor w);
};
private member
Keep implementation details
class window {
private:
int width;
};
Note that C-style casts purposely allows casting a derived class to a protected or private base class in a defined and safe manner and to cast into the other direction too. This should be avoided at all costs, because it can make code dependent on implementation details - but if necessary, you can make use of this technique.
Accessors | Base Class | Derived Class | World
—————————————+————————————+———————————————+———————
public | y | y | y
—————————————+————————————+———————————————+———————
protected | y | y | n
—————————————+————————————+———————————————+———————
private | | |
or | y | n | n
no accessor | | |
y: accessible
n: not accessible
Based on this example for java... I think a little table worth a thousand words :)
To answer that question, I'd like to describe member's accessors first in my own words. If you already know this, skip to the heading "next:".
There are three accessors that I'm aware of: public
, protected
and private
.
Let:
class Base {
public:
int publicMember;
protected:
int protectedMember;
private:
int privateMember;
};
Base
is also aware that Base
contains publicMember
.Base
contains protectedMember
.Base
is aware of privateMember
.By "is aware of", I mean "acknowledge the existence of, and thus be able to access".
The same happens with public, private and protected inheritance. Let's consider a class Base
and a class Child
that inherits from Base
.
public
, everything that is aware of Base
and Child
is also aware that Child
inherits from Base
.protected
, only Child
, and its children, are aware that they inherit from Base
.private
, no one other than Child
is aware of the inheritance.Member in base class : Private Protected Public
Inheritance type : Object inherited as:
Private : Inaccessible Private Private
Protected : Inaccessible Protected Protected
Public : Inaccessible Protected Public
I found an easy answer and so thought of posting it for my future reference too.
Its from the links http://www.learncpp.com/cpp-tutorial/115-inheritance-and-access-specifiers/
class Base
{
public:
int m_nPublic; // can be accessed by anybody
private:
int m_nPrivate; // can only be accessed by Base member functions (but not derived classes)
protected:
int m_nProtected; // can be accessed by Base member functions, or derived classes.
};
class Derived: public Base
{
public:
Derived()
{
// Derived's access to Base members is not influenced by the type of inheritance used,
// so the following is always true:
m_nPublic = 1; // allowed: can access public base members from derived class
m_nPrivate = 2; // not allowed: can not access private base members from derived class
m_nProtected = 3; // allowed: can access protected base members from derived class
}
};
int main()
{
Base cBase;
cBase.m_nPublic = 1; // allowed: can access public members from outside class
cBase.m_nPrivate = 2; // not allowed: can not access private members from outside class
cBase.m_nProtected = 3; // not allowed: can not access protected members from outside class
}
It's essentially the access protection of the public and protected members of the base class in the derived class. With public inheritance, the derived class can see public and protected members of the base. With private inheritance, it can't. With protected, the derived class and any classes derived from that can see them.