Why protected and private inheritance are defined and proposed? I understand some cases private inheritance could be used but it is not recommended. How about protected inheritance?
Can anyone offer me an situation in which protected inheritance is a choice?
I rarely see this.
Thanks so much!
Private inheritance is usually used for mixins---where people inherit to get functionality from the base class, rather than because of "is-a" inheritance.
Protected inheritance can also be used for mixins, where the mixed-in functionality is to be available to downstream classes too.
I generally don't use protected inheritance. In fact, I don't generally use private inheritance. If something does not satisfy the Liskov Substitution Principle then I don't see a reason to use inheritance of any kind; and if it does satisfy LSP then you use public inheritance.
However, the language distinguishes between private and protected only from the class's point of view (that is, code using the class can't tell the difference).
You should use protected inheritance when you want it's semantics, and you should use private when you don't want protected.
See Herb Sutter's Uses and Abuses of Inheritance, Part 1, which is also in his More Exceptional C++ book.
This is a situation i would use Protected inheritance
Base -> Derived1 -> Derived2
I dont want Derived1 to be substituted for the Base class
I want to use functionality in base and also allow the Derived2 to use it without exposing
the functionality to client classes
Related
If i want to inherit from "BaseClass" but i have to manage one of the private members, can i "unprivate" it with something like this?:
using BaseClass::private_member;
If not, what to do when some of the members are NOT marked as protected as it should be? If is not possible, that means we are not supposed to inherit from classes that we did not develop?
If i want to inherit from "BaseClass" but i have to manage one of the private members, can i "unprivate" it with something like this?
No. Private members cannot be managed by derived classes. If you think you have to manage a private member of a base class, then someone's design or implementation is wrong. It might be the base class that is flawed, but keep an open mind – be sure to consider the possibility that the flaw is in your design. (Better yet, assume the flaw is probably in your design until proven otherwise.)
If not, what to do when some of the members are NOT marked as protected as it should be?
First, verify this assumption. Should the member be marked protected, or are you trying to misuse the base class? If the member truly should be marked as protected, then the thing to do is fix the base class. File a bug report if the base class is not under your control.
If is not possible, that means we are not supposed to inherit from classes that we did not develop?
No, that means you should not build upon a flawed foundation. (Or possibly it means that you should work with the base class design instead of against it.) There are plenty of well-implemented base classes out there. Use the right tool for the job at hand.
Public inheritance is easy.
A : public B means every A is a B. In most programming language, like vb.net and objective-c, this is the only type of inheritance.
Private inheritance is also easy but pointless
A : private B means A is implemented by B. However, that's pointless because that means A should contain B instead. Ownership means less coupling with no disadvantage.
Then we have protected inheritance.
Can anyone explain to me what the hell is that for? Some says it's an "as a relationship". I am still not very clear on that.
Does anyone has some sample cases where people uses protected inheritance in good pattern (and conscience) for actual productive use?
Private inheritance is also easy but pointless
A : private B means A is implemented by B. However, that's pointless because that means A should contain B instead. Ownership means less coupling with no disadvantage.
That you might not see reasons for private inheritance does not mean it's pointless.
There are several cases where private inheritance has its reasons. You are right in that at a first glance, private inheritance means has-a relationships just like aggregation, and that private inheritance has a (slightly) tighter coupling.
Reasons for favouring private inheritance over aggretations could be some of the following:
With private inheritance you inherit typedefs as well. In some cases (e.g. traits classes) inheriting privatly is just the alternative to re-typedef tons of typedefs in the base class.
In seldom cases you have to initialize a member before a "real" (i.e. public) base class. The only way to achieve that is by making that member a private base class inherited before the public base.
Some times you need access to protected members of a member. If you can't change the member class itself, you have to use private inheritance to get access to them.
If a member has no data members of its own, it still occupies space. Making it a private base class enables the empty base class optimization, diminuishing the size of your class' objects.
for even more points, see James' comments below
These reasons are obviously technical reasons, some might even say "hacks". However, such reasons exist, so private inheritance is not completely pointless. It is just not "pure OO style" - but C++ isn't a pure OO language either.
The reason for protected inheritance are quite simple once you understood the ones for private inheritance:
If you have reasons to inherit something privately and want to make those benefits (i.e. that would-be member of your class or the typedefs) accessible to derived classes, use protected inheritance. Obviously, private inheritance should be used scarcely, and protected inheritance even more so.
The main motivation for protected inheritance is orthogonality.
in all other contexts, you have three different access controls:
private, protected and public. Why should inheritance be
different? In practice, one could argue that there is no need
or use for protected access in general. That may be overstating
the case, but it is certain that a lot less is protected than
private or public.
Also, private inheritance is not at all pointless, and in fact,
corresponds to the original use of inheritance. As soon as the
base class doing the implementing uses virtual functions which
the derived class has to overload, containment cannot be used.
Bjarne Stroustrup once said that he can address most of the tasks with ONLY private or public member variables and he seldom uses protected member variables in his design. I have heard similar arguments in other places. Here is an example,
class BaseClass
{
...
private:
int m_iAge;
double m_dSalary;
string m_strName;
bool m_bGender;
}
class SubClass : public BaseClass
{
...
}
Given the above class design, how the subclass SubClass can use the variables defined in BaseClass?
Question1> Why we should prefer to having private rather than protected variables? Is it the reason that the BaseClass can hide the implementation detail and make it easy for further improvement?
Question2> In order to let the SubClass access the variable defined in BaseClass, it seems to me that we have to define public access(get/set). However, getter/setter are evil! So the second choice is to define protected access(get/set). Any better idea?
Thank you
Bjarne's point is that generally the derived class shouldn't access the variables of the base class -- doing so frequently leads to maintenance problems. And no, changing it to use get/set (accessor/mutator) functions isn't an improvement.
Ask yourself - why would the derived class ever change the value of m_bGender? Or m_iAge? Doesn't the base class already handle these values correctly?
See, there is generally no need to have direct access to the internals of the base class. So we make them private, and use the class' public interface.
In some very rare cases, there might also be one or two protected functions, if derived classes need some special interface. But that is unusual. If derived classes have different behaviour, we more often use virtual functions for that.
I think the rationale for this claim is that in many situations, subclassing doesn't often change the behavior of the existing (inherited fields), but rather one adds fields and adds new methods that manipulate the new fields.
If you are looking for a way to manipulate inherited members w/o protected, you can, in the base class, make the derived class a friend. You would have to know it ahead of time, though.
The only main reason to use private over protected members is if they indeed are not required in child implementations. That's why we have protected members, because there are cases where the child class does need direct access to members of a parent class. I think Stroustrup is referring to a design whereby there is little need to access parent members in the first place, and child classes simply build upon the functionality of their parent rather than modify the functionality of their parent.
However, getter/setter are evil!
Why so? Getters and setters are an important part of OOP from my experience. There are good reasons to make an interface with a class, rather than access its variables directly.
I was reading Scott Meyers' Effective C++ (third edition), and in a paragraph in Item 32: Make sure public inheritance is "is-a" on page 151 he makes the comment (which I've put in bold):
This is true only for public inheritance. C++ will behave as I've described only if Student is publicly derived from Person. Private inheritance means something entirely different (see Item 39), and protected inheritance is something whose meaning eludes me to this day.
The question: how should I interpret this comment? Is Meyers trying to convey that protected inheritance is seldom considered useful and should be avoided?
(I've read the question
Difference between private, public, and protected inheritance as well as C++ FAQ Lite's private and protected inheritance section, both of which explain what protected inheritance means, but hasn't given me much insight into when or why it would be useful.)
Some scenarios where you'd want protected:
You have a base class with methods where you know you never want to expose the functionality outside, but you know will be useful for any derived class.
You have a base class with members that should be logically used by any class that extends that class, but should never be exposed outside.
Thanks to multiple inheritance you can play around with base classes' inheritance type and construct a more diversed class with existing logic and implementation.
A more concrete example:
You could create a few abstract classes that follow Design Pattern logic, lets say you have:
Observer
Subject
Factory
Now you want these all to be public, because in general, you could use the pattern on anything.
But, with protected inheritance, you can create a class that is an Observer and Subject, but only protected factory, so the factory part is only used in inherited classes. (Just chose random patterns for the example)
Another example:
Lets say for example you want to inherit from a library class (not that I encourage it). Lets say you want to make you own cool extension of std::list<> or a "better" shared_ptr.
You could derive protectedly from the base class (which is designed to have public methods).
This will give you the option to use your own custom methods, use the class' logic, and pass the logic to the to any derived class.
You could probably use encapsulation instead, but inheritance follows the proper logic of IS A
(or in this case IS sort of A)
He isn't exactly discouraging protected inheritance, he just says that he hasn't found any good use for it. I haven't seen anyone either elsewhere.
If you happen to find a couple of really useful use cases, you might have material to write a book too. :-)
Yup, there aren't many uses for protected or private inheritance. If you ever think about private inheritance, chances are composition is better suited for you. (Inheritance means 'is-a' and composition means 'has-a'.)
My guess is that the C++ committee simply added this in because it was very easy to do and they figured, "heck, maybe someone will find a good use for this". It's not a bad feature, it doesn't do any harm, just that no one has found any real use for it yet. :P
Yes and no. I myself think that protected inheritance is a bad feature too. It basicly imports all the base class's public and protected members as protected members.
I usually avoid protected members, but on the lowest levels requiring extreme efficiency with a compiler with bad link-time optimization they are useful. But everything built on that shouldn't be messing with the original base class's (data) members and use the interface instead.
What I think Scott Meyer is trying to say, is that you can still use protected inheritance if it solves a problem, but make sure to use comments to describe the inheritance because it's not semantically clear.
I don't know if Meyers is advising us to refrain from using protected inheritance, but it seems you should avoid it if Meyers is on your team, because at least he won't be able to understand your code.
Unless your co-workers know C++ better than he does, you should probably also stay away from protected inheritance. Everybody will understand the alternative, i.e. using composition.
I can imagine however a case where it could make sense: You need access to a protected member in a class whose code you can't change but you don't want to expose an IS-A relationship.
class A {
protected:
void f(); // <- I want to use this from B!
};
class B : protected A {
private:
void g() { f(); }
};
Even in that case, I would still consider making a wrapper with public inheritance that exposes the protected base members with public methods, then compose with these wrappers.
/*! Careful: exposes A::f, which wasn't meant to be public by its authors */
class AWithF: public A {
public:
void f() { A::f(); }
};
class B {
private:
AWithF m_a;
void g() { m_a.f(); }
};
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
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???????
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
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.
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];
...
};
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.
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.
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.)
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.
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