answersLogoWhite

0


Best Answer

There are essentially just two types of inheritance: single inheritance and multiple inheritance. Single inheritance simply means that one class derives directly from another class. Multiple inheritance means one class is directly derived from two or more classes.

However, since base classes can (and often are) be derived from other base classes, you can think of this type of inheritance as being multi-level. In addition, two or more base classes that share a common base class can use virtual inheritance. What this means is that the common base class becomes a direct base class of the most-derived class, and this one instance is shared, virtually, by all the base classes that would otherwise inherit directly from it. in other words, there is only one instance of the common base class, rather than one instance per class that inherits from it. This is useful in the so-called "dreaded diamond" formation, where a derived class inherits from two base classes, both of which inherit from a common base class.

User Avatar

Wiki User

10y ago
This answer is:
User Avatar
More answers
User Avatar

Wiki User

11y ago

Single inheritance, multiple inheritance, multi-level inheritance and virtual inheritance.

Single inheritance is where a derived class inherits directly from one base class.

Multiple inheritance is where a derived class inherits directly from two or more base classes.

Multi-level inheritance is where a derived class inherits directly from another derived class.

Virtual inheritance is commonly used in multiple, multi-level inheritance, where two or more base classes inherit from the same common base class. The most-derive class then indirectly inherits multiple instances of that common base class, which introduces an ambiguity. By declaring the common base class virtual in the other base classes, the most-derived class directly inherits one instance of the common base class and the base classes then share the same instance of the common base class rather than their own separate instances.

This answer is:
User Avatar

User Avatar

Wiki User

11y ago

There's really only one form of inheritance which is achieved through derivation. That is, derivatives inherit the sum total of all public and protected members of their base classes. However, it isn't quite as simple as that because derivatives can override the member access specified in their base classes. Derived classes may also inherit across multiple levels of base classes (derivatives of derivatives), as well as make use of multiple inheritance, not to mention the use of virtual base classes.

Since all these features can (and often are) combined in many different ways, it's difficult to enumerate them all. Therefore I'll answer the question by highlighting the principal features. As with most things in C++, there is no one-size-fits-all solution but you are of course free to choose which combination of features to apply in order to resolve a particular problem.

Access

As you know, all classes have public, protected and private access sections. Each of these sections determines how the class interfaces with elements that are outwith the class. Note that friends of a class are always considered part of the class interface and have unrestricted access to its members. However friends cannot be inherited. Only class members can be inherited.

When you derive one class from another, the derived class inherits the sum total of the public and protected members of its base class (private members remain private to the class in which they are declared). However, the base class itself may be derived from other base classes (multi-level inheritance), thus your derived class may inherit public and protected members from those classes as well. However, every derivative is free to override access to the members it inherits, either globally or on a per-member basis, thus limiting exposure to those methods from outside of the derived class. This is achieved through public, protected or private inheritance.

Public Inheritance

When you specify public inheritance you are essentially saying that the protected and public members of the specified base class are to remain protected and public with respect to the derived class.

Protected Inheritance

When you specify protected inheritance, the public members of the specified base class become protected members with respect to the derived class.

Private Inheritance

When you specify private inheritance, both the public and protected members of the specified base class become private members with respect to the derived class.

To illustrate these three concepts, consider the following example:

class Base{

private:

int func1();

protected:

int func2();

public:

int func3();

};

class Object1 : public Base {};

class Object2 : protected Base {};

class Object3 : private Base {};

All three object classes inherit from the same base class (Base) but in different ways. It's difficult to see exactly what has been inherited from their declarations alone, but if we expand these class declarations without using inheritance then we can more clearly see how their interfaces would actually be perceived:

class Object1{

protected:

int func2();

public:

int func3();

};

class Object2{

protected:

int func2();

int func3();

};

class Object3{

private:

int func2();

int func3();

};

The first thing to note is that none of these objects inherits func1() because it was declared private in Base -- only Base (and its friends) has access to this member. But each class has inherited func2() and func3() with slightly different levels of access. Note that we haven't changed the way Base works in any way, but we have changed how the underlying Base class is perceived with respect to each of the derived classes.

All three methods can be considered "global" within the scope of the class, because they affect the access of all the inherited members en masses. However, sometimes we only want to alter the access to specific inherited members. For this we use the using keyword, as follows:

Using

Consider the following declaration:

class Object4 : protected Base{

public:

using Base::func2;

};

Here we've specified protected inheritance, so Object4 is essentially the same as Object2. However, in the public section we've declared using Base::func2. What this means is that we are overriding the inheritance of that particular member. In this case, func2 becomes a public member of Object4, rather than a protected member, because it is in the public interface section. If we expand this declaration without using inheritance, we can see this more clearly:

class Object4{

protected:

int func3();

public:

int func2();

};

It should be noted that you cannot override private access of a base class with using. However, through a combination of inheritance and using you can alter the interface to the base class (as perceived from the derived class) in any way you see fit. Ultimately, the goal is to limit the exposure of the derived class interface, regardless of how the base class exposes itself to the derived class.

Multi-Level Inheritance

The above example is a demonstration of single-level inheritance from a single base class. However, the same rules can be applied to multi-level inheritance, where the base class is itself derived from another base class. The number of levels involved is immaterial -- the type of access you specify can only be applied to the interface that was exposed by the most immediate base class, whether that interface was inherited by the base class or declared by the base class, or both. To illustrate, consider the following:

class Base{

private:

int func1();

protected:

int func2();

public:

int func3();

};

class Intermediate : protected Base {

private:

int func4();

protected:

int func5();

public:

int func6();

};

class Object1 : public Intermediate {};

class Object2 : protected Intermediate {};

class Object3 : private Intermediate {};

Again, if we expand these declarations without using inheritance, we can see exactly what each of these objects expose. But let's begin with Intermediate, which inherits from Base with protected access, since that is what is actually inherited by these objects:

class Intermediate {

private:

int func4();

protected:

int func2()

int func3();

int func5();

public:

int func6();

};

Note that func1() is not inherited as it is private to Base. However, from this, we can now see that our three objects will have the following interfaces:

class Object1 {

protected:

int func2()

int func3();

int func5();

public:

int func6();

};

class Object2 {

protected:

int func2()

int func3();

int func5();

int func6();

};

class Object3 {

private:

int func2()

int func3();

int func5();

int func6();

};

Multiple Inheritance

Multiple-inheritance comes into play whenever a derived class inherits from two or more base classes. Each base class is inherited separately (in the order they are specified) and you can specify different levels of access for each, if required, as well as make use of the using for per-member access. By way of example, consider the following:

class Base1{

private:

int func1();

protected:

int func2();

public:

int func3();

};

class Base2{

private:

int func4();

protected:

int func5();

public:

int func6();

};

class Base3{

private:

int func7();

protected:

int func8();

public:

int func9();

};

class Object : public Base1, protected Base2, private Base2{}

Again, through expansion, we can view the actual interface of Object:

class Object{

private:

int func8();

int func9();

protected:

int func2();

int func5()

int func6();

public:

int func3();

};

Virtual Base Classes

A virtual base class is a base class like any other, except that it is inherited virtually. Virtual base classes come into play when multi-level inheritance and multiple inheritance are combined such that intermediate classes share the same base classes. This is best demonstrated with a class model:

class PowerSupply{public: int f;};

class Printer : public PowerSupply{};

class Copier : public Printer{};

In this model, we can access the PowerSupply::f member in a variety of ways using scope resolution via Copier:

Copier::f = 1;

Copier::Printer::f = 2;

Copier::PowerSupply::f = 3;

Copier::Printer::PowerSupply::f = 4;

Each of these is perfectly valid because public access gives us indirect access to f via Copier. The final example is the most explicit form while the others are implicit. As things stand, there is no problem using the implicit calls because there is no ambiguity about what member we are actually accessing. The compiler will automatically upcast for us, just as if we'd used the explicit call.

However, let us suppose that we later decide to separate the scanning component of our copier to create an independent scanner device that can be incorporated within our copier. We begin by redeclaring the classes as follows:

class PowerSupply{public: int f;};

class Printer : public PowerSupply{};

class Scanner : public PowerSupply{};

class Copier : public Printer, public Scanner{};

Note how the Scanner class inherits from the PowerSupply class and that the Copier class now inherits from both the Printer and the Scanner classes.

At first glance this appears to be fine, but there's a fundamental flaw. This becomes more apparent when we attempt to access Copier::f implicitly. We've introduced an ambiguity because there's no way to determine if we meant Copier::Printer::f or Copier::Scanner::f. In other words, Copier has indirectly inherited two separate instances of PowerSupply; one from the Printer class, the other from the Scanner class. This also means that if we alter Printer::f, we do not alter Scanner::f, because they are independent members of Copier.

We could overcome this ambiguity by explicitly upcasting to Printer or Scanner. However, in this case that would be undesirable. In the real world, a copier only has the one power supply which is shared by the scanner and printer components. Our class model should reflect this real-world model and that is where virtual base classes come into play:

class PowerSupply{public: int f;};

class Printer : public virtual PowerSupply{};

class Scanner : public virtual PowerSupply{};

class Copier : public Printer, public Scanner{};

Note that the virtual keyword may be placed before or after the access specifier, it makes no difference.

With this declaration, PowerSupply becomes a virtual base class. What this means is that Copier now directly inherits just one instance of PowerSupply (just as if it were derived directly from PowerSupply), and Printer and Scanner now share that one instance. Thus Copier::f is a perfectly legal way of accessing PowerSupply::f. Moreover, Printer::f and Scanner::f are now one and the same member, so if you change either one, you automatically change both. This is the expected behaviour of this particular class.

"Dreaded Diamond"

The scenario described above is often called the "dreaded diamond". To try and illustrate, here's how the class hierarchy can be imagined both with and without abstract base classes:

Without Virtual Base Class

("Dreaded Diamond")PowerSupplyPowerSupply||PrinterScanner\/CopierWith Virtual Base Class

(Diamond)PowerSupply/\PrinterScanner\/Copier

As you can see, the so-called "dreaded diamond" on the left isn't even a diamond (its more like a fork), so its not clear where this phrase originated. The real diamond, on the right, is certainly not dreaded; if anything, it is desired.

The above diagrams are conceptual of course; the actual layout in memory is quite different, but they help visualise the inheritance chain. Although the memory footprint of the virtual base class is usually smaller than the "dreaded diamond" formation, there is a small cost involved in creating the virtual table.

Note that in either case, the Scanner and Printer are still independent classes and can still be instantiated as independent objects, each with their own independent PowerSupply components. More importantly, the virtual keyword applies to derivatives of Scanner and Printer, not to Scanner and Printer themselves. Moreover, it applies to derivatives of their derivatives. Thus we could derive FaxMachine from Copier and it will then inherit directly from PowerSupply.

This answer is:
User Avatar

User Avatar

Wiki User

7y ago

Inheritance occurs when one class derives from another, such that the derived class inherits all the public and protected properties of its base class.

There are two types of inheritance: single inheritance and multiple inheritance. Single inheritance applies to derived classes that inherit from just one base class. Multiple inheritance applies to derived classes that inherit from more than one base class. Single and multiple inheritance may be used in combination to create more complex class hierarchies. That is, class A and B may be base classes of C (multiple inheritance) while class D inherits from C (single inheritance).

With multiple inheritance hierarchies, there may be cases where two or more classes are derived from the same base class, thus creating two or more separate instances of that class within the hierarchy. This creates an ambiguity when implicitly referring to the members of that class via a derived class that inherits two or more of those instances because the compiler won't know which instance is being referred to. We can obviously refer to each explicitly, however this is far from intuitive so it's usually better to combine all separate instances into a single instance using virtual inheritance. That is, if we suppose class A is a base of both B and C while D inherits from both B and C, then D has access to two separate instances of A (explicitly referred to as D::B::A and D::C::A). Unless we have a specific requirement for multiple instances of A, we will want to combine those instances into a single instance. To achieve this, A must be declared a virtual base of both B and C. Virtual bases are constructed by the most-derived class in the hierarchy, so in this case D will construct the one and only instance of A while B and C will be constructed from that common base rather than constructing their own individual bases (any initialisers for A that are explicitly defined in B or C will simply be ignored). Where B or C are themselves the most-derived class in the hierarchy, they will be constructed in the normal manner just as if A were declared non-virtual (any initialisers for A explicitly defined by B or C will be invoked as normal).

In addition to single, multiple and virtual inheritance, access to inherited members can be redefined using public, protected or private access. Public inheritance is the default for struct data types while private is the default for class data types. Note that we cannot raise the access level of base class members, we can only retain the current access levels or reduce them.

With private inheritance, both the public and protected members of the base class become private members with respect to the derived class and are therefore only accessible from within the derived class and to friends of the derived class. With protected inheritance, the public members of the base class become protected members with respect to the derived class. Protected members are accessible from within the derived class, friends of the derived class and (unless the class is declared final) to derivatives of the derived class and their friends. With public inheritance, the public members of the base class remain public with respect to the derived class and are accessible from any function. Protected members remain protected and remain accessible as per the aforementioned protected inheritance. As well as defining inheritance access for the class as a whole, access can also be specified on a member-by-member basis to achieve fine-grained access control over base class members.

If a base class has member data, it is usually a design error to make that data available through public or protected access as this could potentially undermine the class invariant. It also makes it that much more difficult to change the representation of the data in a non-intrusive manner. Ideally, virtual bases should contain no data members other than static data members (thus making it that much easier to combine them into single instances). Virtual bases are usually best implemented as abstract base classes (classes with at least one pure-virtual function). All classes intended to be used as base classes must have a virtual destructor to ensure correct tear-down. Classes without virtual destructors are not intended to be used as base classes.

If a base class has member data that needs to be accessible, always provide a protected and/or public interface as required. Member functions of the base class are expected to be public or protected members (depending on whether they are intended for normal users or class implementers, respectively) unless they are an implementation detail of the base class in which case they should be declared private. In other words, never expose more than needs to be exposed. That simple rule applies to any class. Even if the class has no invariant, always provide an interface as you never know when you might need to change the class representation. The fewer details you expose outside the class and friends of the class, the more easily this can be achieved.

This answer is:
User Avatar

User Avatar

Wiki User

12y ago

There are 5 types of inheritence:

1.single inheritence

2.multilevel inheritence

3.hirarchical inheritence

4.hybrid inheritence

5.multiple inheritence

This answer is:
User Avatar

User Avatar

Wiki User

14y ago

types of inhertance

This answer is:
User Avatar

Add your answer:

Earn +20 pts
Q: Explain types of inheritance in c plus plus?
Write your answer...
Submit
Still have questions?
magnify glass
imp
Related questions

What is an inheritance Explain different types of inheritance in c?

C is not an object oriented language and therefore has no native support for inheritance.


Does c plus plus supports hierarchical inheritance?

Yes.


How ploymorphism and inheritance is different from that in Java and c plus plus?

C++ allows multiple inheritance while Java does not. In my opinion, multiple inheritance is not useful because it can get very confusing very quick. For polymorphism, C++ does early binding by default, while Java does late binding by default. Late binding is more useful than early binding.


Write a c plus plus programme to illustrate single inheritance?

struct A {}; // base class struct B : A {} // derived class (single inheritance).


How can a constructor be invoked at the time of inheritance in C Plus Plus?

It cannot. Inheritance is a compile-time operation. Constructors are invoked at runtime at the point of instantiation.


In C plus plus How would you use Inheritance to create an Orange?

One way would be to define a base class called fruit, from which you could derive specific types of fruit, including an orange.


Demonstrate single inheritance in C plus plus?

struct base1 { // ... }; struct base2 { // ... }; struct derived1 : public base1 // single inheritance { // ... }; struct derived2 : public base1, public base2 // multiple inheritance { // ... };


Explain any six file commands in C plus plus?

There's no commands in C++.


Do I need types of design patterns in c plus plus?

No.


What are the concepts of object oriented programming in c plus plus?

The concepts of OOP in C++ are the same as for OOP in any other programming language: abstraction, encapsulation, inheritance and polymorphism.


Explain the different types of constants n variables in C?

explain loop structrunes


How do you implement inheritance in c plus plus?

You implement inheritance by deriving a new class of object from an existing class of object. The existing class is known as the base class of the derived class.Classes declared final cannot be used as bases classes and classes without a virtual destructor (or a virtual destructor override) cannot be used as polymorphic base classes.