Introduction
Inheritance is the way of inheriting some property of some existing class (which is called as Base class) in new class (which is called as Derived class). Derived class can inherit and expose public area of Base, and inherit protected area of Base, but can''t inherit
private area of Base.
While inheriting from a Base, Derived class'
s public functions won't get access to Base's private area. Derived class can access/modify private area of Base, only if Base has some public/protected members, which allow doing so. The reason for this restriction is obvious. By allowing so, this will lead to changing the state of a class just by inheriting it publicly. It's the responsibility of Derived class to call the Base class's constructor with
proper initializes while constructing Derived class. By default, compiler will call the default constructor of its Base. Base class's constructors can be called explicitly from initialization list, when we want to initialize them with some particular value.
Even though Derived class can inherit public/protected members of Base, it can't inherit constructors, destructor and assignment operators of Base even if they are public. The reason is, these operations are Base specific. They construct/destruct/assign only Base part of a class. But these functions are silently called by the compiler from the Derived class's constructor/destructor/assignment operator.
There is a general misconception that “Inheritance is for code re-use”. Here there are some tips on Inheritance:
- Inheritance is not for code re-use; it's for flexibility. It is composition, which is for code re-use.
- Use inheritance only if doing so will remove if/else/switch statements from the caller of code.
- Inheritance will be more effective and useful with dynamic binding, that is, with virtual functions.
- Try hard to make all your Base classes as Abstract Base Class (ABC)
- Keep as little data as possible in ABC with most member functions as pure virtual. This will avoid situations where we need to inherit data/code along multiple paths.
- There is some overhead with Multiple Inheritance (MI). Compiler will have to add some more code when we refer a derived class object using its Base reference/pointer. This requires “this” pointer alignment. Still, it's not a bad idea to use MI as long as it gives the efficiency. There are other alternatives for MI like Bridge pattern, nested generalization with its own advantage and
disadvantage. Before using MI, think of those alternatives and go for the best one which suits your design.
C++ Inheritance
Hi Girish, I like the fact that your articles explain a lot of programming concepts as opposed to most of the articles which are basically "How-Tos".
Can you please explain Reason No. 2 in "Reasons to use inheritance". What is the connection between using if/else/ switch statements and using inheritance
C++ Inheritance
Hi,
>> Can you please explain Reason No. 2 in "Reasons to use inheritance". What is the connection between using if/else/ switch statements and using inheritance
Its like this, when we have multiple decisions to check and perform different operation depending on the condition (decision), then we can think of doing the same thing with Inheritance. Have one base class with a method for operation and as many as number of conditions (decisions) of Derived class deriving from that base class and having its own implementation for that operation declared in base class.
I can give you one example like this, eventhougth this one is bit specific example
draw_circle();
}
else if(shape == triangle) {
draw_triangle();
}
else if(shape == rectangle) {
draw_rectangle();
}
else if(shape == line) {
draw_line();
}
In the above scenario, we can design our requirement as below. Have a base class as Shape with Draw as virtual fun. Implement Circle, Triangle, Rectangle, Line derived from Shape with its own implementation for Shape.
Regards Girish
C++ Inheritance
HI Girish,
Could you explain point 1. more elaborately with sample code?
Thanks in Advance SAhu
C++ Inheritance
"Inheritance is not for code re-use; it's for flexibility. It is composition, which is for code re-use"
To explain it in very simple words - When we have composition (Class B having object of Class A), now B can use the functions of class A. That is re-using the functionality of A for some other purpose with in Class B.
But, it makes inheritance more meeningful when we derive from (lets say class A) to give a different implementation in derived class. We can use the object of derived class as if its object of base class and we can get the different behavior also. Thats what the flexibility is. For getting more complex picture, you can read more about some of the design principles like Dependency Inversion Principle (DIP), Liskov Substitution Principle (LSP).
Regards Girish
C++ Inheritance
I have a basic question.
Instead of the following code:
if(shape == circle) draw_circle(); else if(shape == triangle) draw_triangle(); else if(shape == rectangle) draw_rectangle(); else if(shape == line) draw_line();
Would it not be better to have a virtual function draw(), and the above if/else code could be replaced with a single call to the draw() function that is implemented in the derived class.
If some if/else logic is required based upon the object type, can the typeid() keyword be used in Symbian OS to find out the type of the object?
C++ Inheritance
Hi,
I have been looking for rules or recommendations for this issue: which type of classes are you allowed to inherit from which types of classes? E.g., is it OK to inherit an R class from a T class? I understand M classes are supposed to be used for multiple inheritance and C classes always derive from CBase. But are there any other rules existing, for other class types?
Regards, Pete
I have a doubt
Suppose there is a base class "Base" and a derived "Derived";
And there are some casting expressions such as,
Even if the derived class has all (almost) the properties of the base class, why the pointer of its type cannot be used to hold the object of Base class??
Base *bptr; Derived d; b =
You can see the derivation as a IS-A relationship. So in your example, "derived" IS-A "base" with added feature. So whenever you can use a "base" object, you can use a "Derived" object since it has all the required feature. In the snippet above, d IS-A Derived so IS-A base as well. Thus the bptr=&d; expression is valid.
The reverse is however not true. Derived IS-A base but Base is not a Derived since it does not implement all new functions introduced by Derived (nor it has the same data member). So here, you are trying to affect the dptr pointer with something with is just "half a derived".
You can try to use "reinterpret_cast" primitive to force the affectation but this will be very dangerous in your case.