private inheritance

Jul 23, 2009 at 4:45pm
Hey,

I'm now learning about inheritance and I understand it up to this point. I understand how to use private inheritance, but don't understand what it actually does.

A tutorial says it makes all public methods from the parent class private. Now, I don't really understand that anymore. Doesn't that make the class unusable?

Can anyone please give me a very simple example to demonstrate the use of it?

Thanks =)
Jul 23, 2009 at 5:15pm
It's difficult to come up with a simple example because the instances in which you would use protected and private inheritance are more complex. In simple situations, you're better off avoiding them completely.

Public inheritance implies an "is a" relationship. If Poodle is (publically) derived from Dog, then a Poodle "is a" Dog.

Protected/Private inheritance change this relationship to more of a "has a" relationship. If Computer is privately derived from Motherboard then a Computer "has a" Motherboard. The thing is, it's much easier (and safer) to form a "has a" relationship by simply making Motherboard a member of Computer, rather than deriving from it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Motherboard {};

// this makes a "has a" relationship
class Computer : private Motherboard
{
};

// this makes a similar "has a" relationship
//  this approach is aka "composition"
class Computer
{
private:
  Motherboard mobo;
};


One advantage to using protected/private inheritance instead of composition is that the derived class has access to protected members in the parent class. However this is kind of a double-edged sword, as it becomes easier to misuse the class.

Another advantage is the parent class can more easily call functions in the derived class by way of virtual functions. This allows for a sort of "two way" communication between classes.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Parent
{
public:
  virtual void CallChild() = 0;

  void DoStuff()
  {
    CallChild();  // calls a function in the child class
  }
};

class Child : private Parent
{
public:
  virtual void CallChild() { /*...*/ }
};


This sort of relationship is a bit harder (but not impossible) to accomplish with the composition approach.


Protected/private inheritance isn't used that often. I can't recall a time when I had to use it.
Jul 23, 2009 at 6:11pm
Thank you, that explains a lot.

So it's better to not pay too much attention to this because it's quite useless?

If we have this class:
1
2
3
class Computer : private Motherboard
{
};


What are the limitations of the Computer class (I refer to "it makes all public methods from the parent class private"). If the Motherboard class has a method, can't computer objects use the method?
Last edited on Jul 23, 2009 at 6:11pm
Jul 23, 2009 at 7:50pm
Well it's not that it's useless, it's just that it's only useful in a very specific set of circumstances. More often than not you're better off using composition for "has a" relationships.


What are the limitations of the Computer class (I refer to "it makes all public methods from the parent class private")


Computer itself is not limited. In fact the Computer class has more options available to it (vs. composition) because it can access protected members in Motherboard, something it wouldn't be able to do with composition.

Other code that uses Computer objects cannot access Motherboard members on those objects because Computer no longer has a "is a" relationship like it does with public inheritance.

Example:

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
class Motherboard
{
public:
  void Foo();

protected:
  void MooCow();
};

class Computer : private Motherboard
{
public:
  void Bar()
  {
    Foo();  // this is okay.  It calls Motherboard::Foo()
    MooCow(); // this is also okay because Computer can access protected
           // Motherboard members
  }
};

int main()
{
  Computer comp;
  comp.Foo();  // this is a compiler error.  See below for explanation
  return 0;
}


Technically... comp.Foo() errors because all members of Motherboard become private within Computer. Even though Motherboard has Foo as a public function, it is private in Computer because of private inheritance. This is what "it makes all public methods from the parent class private" means.

Conceptually... comp.Foo() errors because Computer does not have a Foo function. Motherboard does, but Computer does not have an "is a" relationship with Motherboard.. therefore you can't treat a Computer like it was a Motherboard (like you could if it was public inheritance).
Jul 23, 2009 at 9:16pm
Very well said, Disch.

More reading here
http://www.parashift.com/c++-faq-lite/private-inheritance.html
Jul 24, 2009 at 7:46am
Very nice explanation, I understand it now.

Thank you very much, Disch and thanks Duoas for the link =)
Topic archived. No new replies allowed.