0

I have a question with regards to classes

// Using private inheritance 
class CardPile : private vector<Card*> { 
    public: 
        CardPile (); 
        virtual ~CardPile ();  
        void add (Card* card); 
        void add (CardPile & otherPile); 
        void remove (Card* card); 
        void shuffle (); 

What does "private vector< Card* >" mean exactly? Does this mean I inherit all the public members of the vector class? Do I have access to the vector private members as well? How would this vary if it was protected or public instead of private? Clarification would be appreciated

juanchopanza
  • 223,364
  • 34
  • 402
  • 480
Masterminder
  • 1,127
  • 7
  • 21
  • 31
  • 6
    `: private vector< Card* >` means "this is bad code". – ipc Nov 27 '12 at 16:18
  • Do not inherit from the `std` namespace! – bitmask Nov 27 '12 at 16:19
  • 1
    Inheriting privately a vector is not a bad thing *per se*, if you are bringing selectively members of the vector into your class (eg. via `using std::vector::operator[]`, etc). Here I think that having a private vector member is vastly superior. – Alexandre C. Nov 27 '12 at 16:20
  • 2
    You can inherit from stl objects, but only if it's to add functionality that's not there. Seeing that you don't want anyone to access your vector, I'd suggest adding a private: vector m_pile; to your class – Nico Nov 27 '12 at 16:21
  • suppose I wanted to make a method to access the vector in cardpile class and add an element to that vector, how would that look like? Vector would have public accessor methods like push_back,begin(), add, remove – Masterminder Nov 27 '12 at 16:39

2 Answers2

9

Private inheritance gives you access to the public and protected methods of the base class, just like public inheritance. The difference is that the methods are private to your class. Similarly for protected inheritance. You get the public and protected methods of the base class, and they are all protected in your class.

Private inheritance allows you to implement a class in terms of another class and is not that dissimilar from having a private data member of that class. In this sense, a class that inherits privately or "protectedly" from another has a "has-a" relationship with it, as opposed to the "is-a" relationship of public inheritance. This means for instance that the Liskov substitution principle does not apply.

Now, in your particular example, inheriting from standard library containers is considered poor form, but note that most of the arguments apply to public inheritance.

class Foo
{
  void privateFoo() const {}
 public:
  void foo() const {}
};

class Bar : Foo // class inheritance is private by default
{
 public:
  void bar() const { 
    foo(); // OK, foo() is a private method of Bar.
    privateFoo(); // Error! privateFoo() is private to Foo.
  }
};

int main()
{
  Foo f;
  f.foo(); // OK
  Bar b;
  b.bar(); // OK, calls foo() internally
  b.foo(); // Error! foo() is private in Bar.
}
Community
  • 1
  • 1
juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • Thanks for the response. Could you give me an example of what you mean exactly, been reading up on this and do not seem to clear about it. So suppose vector class has begin(), push_back etc. all of these are accessible to the child and I have access to the vector classes private members? – Masterminder Nov 27 '12 at 16:23
  • Okay, suppose I wanted to make a method to access the vector in cardpile class and add an element to that vector, how would that look like? – Masterminder Nov 27 '12 at 16:33
  • @Masterminder You don't get access to the base class' private methods, onlt the public and protected ones. And they are private in your derived class. – juanchopanza Nov 27 '12 at 16:34
  • Okay well like suppose vector has accessor methods like push_back, begin(), or any add/remove functions that add elements to the vector. How would I access them from the cardPile class? – Masterminder Nov 27 '12 at 16:37
  • @Masterminder you can do two things. 1) add a push_back method to your class that calls the vector's push_back method. 2) put `using std::vector::push_back` in a public section of your derived class. This makes all vector's `push_back` methods public in your class. – juanchopanza Nov 27 '12 at 16:37
  • ,how look like for the first way you suggested? – Masterminder Nov 27 '12 at 16:42
  • I am referring to the adding a push_back method to your class that calls the vector's push_back method – Masterminder Nov 27 '12 at 16:45
  • @Masterminder for example `void push_back(Card* c) { vector::::push_back(c);}`. But I really suggest holding a vector as a private data member instead of the inheritance. – juanchopanza Nov 27 '12 at 16:45
  • Well isn't the vector a private member in the vector class? You have push_back to push add an element at the end and then in cardpile you can add a card through the push_back method defined in cardpile( which uses the push_back method of the vector class) – Masterminder Nov 27 '12 at 16:52
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/20184/discussion-between-juanchopanza-and-masterminder) – juanchopanza Nov 27 '12 at 16:54
0

Visibility in inheritance is subject to exactly the same rules as in composition.

That is, CardPile inherits from vector<Card*> in the same way as it would if it was public inheritance. The difference is that scope or type can know about this inheritance except CardPile and its friends.

bitmask
  • 32,434
  • 14
  • 99
  • 159
  • suppose I wanted to make a method to access the vector in cardpile class and add an element to that vector, how would that look like? – Masterminder Nov 27 '12 at 16:34
  • @Masterminder: Just invoke the `std::vector::push_back(Card*)` member function, which you can access in `CardPile`. – bitmask Nov 27 '12 at 16:48