tags:

views:

190

answers:

8

suppose i have a class engin and i inherit a class car from engin class

class engin
{
    public:
        engin(int nobofcylinders);
        void start();
};
class car:private engin
{
    public:
        car():e(8){}
        void start()
        {
            e.start();
        }
    private:
        engin e;
};

now the same can be done by the composition, the question is which approch would be best and is mostly used in programming, and why???????

+4  A: 

If you want to compare private inheritance with composition, read http://www.parashift.com/c++-faq-lite/private-inheritance.html#faq-24.3. I don't think private inheritance is good.


A Car has-an Engine, but a Car is-not-an Engine, so it should be better done with composition.

Inheritence is useful for "is-a" relationships, e.g. a Bus is-a Car, a Car is-a vehicle, etc.

Composition is useful for "has-a" relationships, e.g. a Car has Wheel-s, a Car has-an Engine, etc.

So a logical code should be like

class Car : public Vehicle {
    Engine engine;
    Wheel  wheels[4];
    ...
};
KennyTM
Private inheritance does *not* model a has-a relationship. The name “inheritance” is simply misleading here. Rather, it models an is-implemented-in-terms-of relationship (which wouldn’t be appropriate here either).
Konrad Rudolph
+1, there is hardly more to say :)
frunsi
Well, private inheritance does not create an is-a relationship. I agree composition is better.
anon
but it can be done with private inheritance, you are not following my question, my question is we can do it both ways either with composition or private inheritance , which approch is best and mostly used in programming
Zia ur Rahman
@Konrad Rudolph: The "is-implemented-in-terms-of" relationship is rather similar to an "is-a" relationship, and the difference does not matter in this case. Its still wrong to implement a car in terms of an engine...
frunsi
+1 excatly the example I was about. @Zia if you're still unsatisfied rethink, all you wan't to know is in there.
stacker
@frunsi: I agree about this particular example – but I do not agree about “is-implemented-in-terms-of” being similar to “is-a” because there’s a **major** difference: “is-a” relationships must. not. violate the Liskov substitution principle (one of the corner stones of object oriented design) – while “is-implemented-in-terms-of” may do just that. In fact, private inheritance is just notation; it doesn’t have to follow any of the fancy inheritance rules.
Konrad Rudolph
I don't think that we can compare composition and "is-implemented-in-terms-of". Rather, i think composition is a technique to achieve the latter, and private inheritance is another technique to achieve this too. What else is "car has-an engine, 4 wheels and stuffs" than "car is-implemented-in-terms-of an engine, 4 wheels and stuffs"?
Johannes Schaub - litb
@Konrad Rudolph: You're right when considering an outside view to the class. But from an inner view, private inheritance is still an "is-a" relationship. The conclusion is the same (composition fits better) as most people here wrote, and private inheritance somehow combines disadvantages of composition and public inheritance, and is not well suited for the example.
frunsi
@frunsi, if you use containment, i think you *are* implementing a car in terms of an engine. All you don't do is to access the engine's members using `this` (as said by Neil, this has the benefit of having multiple contained entities). But indeed has-a is quite similar to is-implemented-in-terms-of (i don't even see a difference there), and not so much to is-a, i think.
Johannes Schaub - litb
@Johannes Schau: Well, ok, you are right. I think, viewing it through different positions we are all right ;-) In practice, the memory layout of `class Derived : private Base` usually is the same as if Base would be a private member of Derived, and everything else is just notation, as Konrad said...
frunsi
+5  A: 

Composition is to be preferred for two main reasons:

  • the thing(s) being composed can have names
  • you can compose more than one thing of the same type
anon
I tend to agree – but private inheritance is something of an established pattern in C++ when it comes to policy classes (allocators etc.).
Konrad Rudolph
There's another major reason: Inheritance, public or private, comes with much closer coupling than composition. And lose coupling is to be preferred.
sbi
@sbi: especially since composition can be used through Pimpl :)
Matthieu M.
+3  A: 

Private inheritance, despite the name, isn’t really inheritance – at least not from the outside (of the class), where it matters.

For that reason, different rules apply. In C++, private inheritance is said to model an “is implemented in terms of” relationship. Thus, a priority queue which is implemented in terms of a heap, could look like this:

template <typename T, typename Comp = std::less<T> >
class priority_queue : private heap<T, Comp> {
    // …
};

Personally, I don’t see the advantage of this pattern, and Neil has already stated that in most cases, composition actually has the advantage over private inheritance.

One advantage exists, though: since it’s such an established pattern, the meaning of a private inheritance is immediately clear to a seasoned C++ programmer; the above code would tell them that the priority queue is implemented in terms of a heap – which wouldn’t be obvious if the class just happened to use a heap as one of its members.

Private inheritance tends to get used in C++ primarily for policy classes. The classical example is allocators, which determine how a container class manages storage internally:

template <typename T, typename A = std::allocator<T> >
class vector : private A {
    // …
};

No harm done. But once again, this could also have been done using composition.

Konrad Rudolph
+3  A: 

Usually, composition is to be preferred (others gave the major reasons), but private inheritance allows things which can't be done by composition:

  • zero-size base class optimization (a base class of size zero will not increase the size of a class, a member of size zero will), that't the reason behind its use for policy classes which often have no data members

  • controlling initialization order so that what is composed is initialized before a public base

  • overriding a virtual member in what is composed

  • with private virtual inheritance, ensuring that there is only one composed thing even if one do it in several bases

Note that for the later two uses, the fact that the base class exist can be observed in a descendant.

AProgrammer
I don't like the 3rd point: I prefer to override the virtual methods via a publicly inheriting class and the use this class in composition.
Matthieu M.
@Matthieu, It's an alternative. But if the only justification of the new class is that it allows composition instead of private inheritance, I'd probably not use it -- it does not justify to have two tighly coupled classes. And if not, the class has probably enough purposes without bringing the fact it prevents a private inheritance.
AProgrammer
+2  A: 

Composition is used more than private inheritance. The general rule I follow and would recommend is that unless you have a specific reason to use private inheritance you should use composition.

Composition has many benefits over private inheritance:

  • You can have more than one instance of a particular class.
  • You don't pollute your class' namespace with a bunch of private functions that don't make sense for your class.
  • You can give names to the parts of your object
  • Your class is less coupled to the classes it's composed of than it is to a class it inherits from
  • If you discover you need to swap out an object that you've included by composition during the lifetime of your object, you can, with private inheritance you're stuck.

There are a lot of other benefits to composition. Basically, it's more flexible and cleaner.

There are reasons to use private inheritance though. They are very specific reasons, and if you think they apply, you should think carefully about your design to make sure you have to do it that way.

  • You can override virtual functions.
  • You can get access to protected members of the base class.
  • You need to pass yourself to something that wants an object of the class you're inheriting from (this usually goes hand-in-hand with overriding virtual functions).

And there are a few rather tricky ones as well:

  • If you use composition for a class that has 0 size, it still takes up space, but with private inheritance it doesn't.
  • You want to call a particular constructor for a virtual base class of the class you're going to privately inherit from.
  • If you want to initialize the private base before other base classes are initialized (with composition, all the variables in your class will be initialized after all your base classes are).
  • Using private virtual inheritance to make sure there's only one copy of a thing even when you have multiple base classes that have it. (In my opinion, this is better solved using pointers and normal composition.)
Omnifarious
+2  A: 

I prefer to think of inheritance as derived is a kind of base, that basically means public inheritance. In case of private inheritance it more like derived has a base, which IMHO doesn't sound right, because that's IMHO the work for composition not inheritance of any kind. So, since private inheritance and composition essentially mean same thing logically, which to choose? With the example you posted, I'd most certainly go for composition. Why? I tend to think of all kinds of inheritance as a kind of relationship, and with the example you posted, I can't think of a situation where I could say a car is kind of an engine, it simply isn't. It's indeed like a car has an engine, so why would a car inherit from an engine? I see no reason.

Now, indeed there are cases where it's good to have private inheritance, namely boost::noncopyable, with it's ctor/dtor being protected, you'd have hard time instantiating it, and indeed since we want our class to have a noncopyable part, that's the only way to go.

Some style guides (e.g. google c++ style guide) even recommend to never use private inheritance, for reasons similar to what I already written - private inheritance is just a bit confusing.

Hope it helps.

Dmitry
ya this is the answer that i was expecting. thank your sir.
Zia ur Rahman
@Zia Not to criticise this answer, but the point of SO is not to provide the questioner with answers they are "expecting", but to provide answers that are technically correct.
anon
A: 

Base classes are evil.

In my mind, good OO design is about encapsulation and interfaces. The convenience of base classes are not worth the price you pay.

Here's a really good article about this:

http://www.javaworld.com/javaworld/jw-08-2003/jw-0801-toolbox.html

steve a
+1  A: 
  • Private inheritance means is-implemented-in-terms of. It's usually inferior to composition, but it makes sense when a derived class needs access to protected base class members or needs to redefine inherited virtual functions.

  • Unlike composition, private inheritance can enable the empty base optimization. This can be important for library developers who strive to minimize object sizes.

Scott Meyers "Effective C++" Third Edition.

Sergey Teplyakov