Inheritance is a type of
relationship.
It involves sharing of attributes and operations
among classes.
A base class defines a set of common
attributes and operations which it shares with derived classes.
A derived class extends the resources
provided by the base class by adding its own data members and member
functions.
For example,
Inheritance
- combines with object composition to create the
primary techniques for reusing software.
- involves a class hierarchy
whose elements are base and derived classes.
- A base class provides member functions and data
to a derived class.
- The derived class might choose to add its
own member functions or redefine existing ones in
the base class.
General Form of Derived Class:
class
derived-class-name:access
base-class-name
{
//...
}
where
access is one of three keywords:
public, private,
or protected.
-
When the access specifier for the inherited base class is public,
all public members of the base class become public members
of the derived class.
-
When the access specifer is private,
all public members of the base class become private members
of the derived class.
-
In either case, any private members of the base remain private to
it and are inaccessible by the derived class.
-
In order to ONLY let the derived class (other than the base class) to access,
the base class needs to specify its members as protected
instead of
private.
-
For the protected members of
base class, if inherit access is
-
public - they become protected
members of the derived class.
-
private - they become private
members of the derived class.
-
protected - they become protected
members of the derived class.
-
The public members of base class become
protected members of the derived class
when the inherited method is protected.
Example 1: Inherit as public.
#include <iostream>
using namespace std;
class
base {
int x;
public:
void setx(int
n) { x = n; }
void showx() {
cout << x <<'\n'; }
};
//Inherit as public.
class
derived : public base
{
int y;
public:
void sety(int
n) { y = n; }
void showy() {
cout << y << '\n'; }
};
void
main()
{
derived ob;
ob.setx(10);
// access member of base class
ob.sety(20);
// access member of derived class
ob.showx();
// access member of base class
ob.showy();
// access member of derived class
/*
Although it is inherited as public, it can not
access
private mewmber. The following is illegal.
cout << ob.x <<endl;
*/
}
Exampler 2: Inherit as private.
#include <iostream>
using namespace std;
class
base {
int x;
public:
void setx(int
n) { x = n; }
void showx() {
cout << x <<'\n'; }
};
//Inherit as private.
//Access
setx() and showx() from within derived class.
class
derived : private base {
int y;
public:
void setxy(int
n, int m) { setx(n); y = m; }
void showxy()
{ showx(); cout << y <<
'\n'; }
};
void
main()
{
derived ob;
/*
setx() becomes private to derived class.
Therefore
the following are illegal.
ob.setx(10);
ob.showx();
*/
ob.setxy(10, 20);
ob.showxy();
}
Example 3: Inherit as public
with protected
members in base.
#include <iostream>
using namespace std;
class
base {
protected:
// private to base
int a, b;
// but still accessible by derived
public:
void setab(int
n, int m) { a = n; b = m; }
};
class
derived : public base {
int c;
public:
void setc(int
n) { c = n; }
//
this function has access to a and b from base
void showabc()
{
cout <<
a << ' ' << b << ' ' << c << '\n';
}
};
void
main()
{
derived ob;
/*
a and b are not accessible here because they are
private to both base and derived
the following is illegal.
cout << ob.a << endl;
*/
ob.setab(1, 2);
ob.setc(3);
ob.showabc();
}
Example 4: Inherit as protected
with protected
members in base.
#include <iostream>
using namespace std;
class
base {
protected:
// private to base
int a, b;
// but still accessible by derived
public:
void setab(int
n, int m) { a = n; b = m; }
};
class
derived : protected base {
int c;
public:
void setc(int
n) { c = n; }
// this function
has access to a and b from base
void showabc()
{
cout <<
a << ' ' << b << ' ' << c << '\n';
}
};
void main()
{
derived ob;
/*
setab() is not accessible here because it is
protected from derived.
the following is illegal.
setab(1, 2);
*/
ob.setc(3);
ob.showabc();
}
Constructors, Destructors, and Inheritance
When a base class and a derived class both have constructor
and destructor functions, the constructor
functions are executed in order of derivation. The
destructor functions are executed in
reverse order.
Example:
#include <iostream>
using namespace std;
class base {
public:
base() { cout
<< "Constructing base class\n"; }
~base() { cout
<< "Destructing base class\n"; }
};
class derived : public
base {
public:
derived() { cout
<< "Constructing derived class\n"; }
~derived() { cout
<< "Destructing derived class\n"; }
};
void main()
{
derived ob;
}
The program displays the following output:
Constructing
base class
Constructing derived
class
Destructing derived
class
Destructing base
class
Passing Arguments from derived constructor to base constructor:
Example:
#include <iostream>
using namespace std;
class
base {
int i;
public:
base(int
n) {
cout <<
"Constructing base class\n";
i = n;
}
~base() { cout
<< "Destructing base class\n"; }
void showi() {
cout << i << '\n'; }
};
class
derived : public base {
int j;
public:
derived(int
n, int m) : base(m)
{ //pass arg to base class
cout <<
"Constructing derived class\n";
j = n;
}
~derived() { cout
<< "Destructing derived class\n"; }
void showj() {
cout << j << '\n'; }
};
void
main()
{
derived ob(10,
20);
ob.showi();
ob.showj();
}
Output:
Constructing
base class
Constructing derived
class
20
10
Destructing derived
class
Destructing base class
Multiple Inheritance:
Create a multilevel class hierarchy
indirect
base class -> base class -> derived class |
Combine two or more base classes
to create a derived class |
|
|
Virtual Base Classes:
|
This causes ambiguity when a
member of Base is used by Derived3.
Since two copies of Base are included in Derived3, is a reference to
a member of Base referring to the Base inherited indirectly through Derived1
or to the Base inherited indirectly through Derived2? |
Solution: Use a virtual base class
to prevent two copies of base from being present in derived3.
Example:
#include <iostream>
using namespace std;
class
base {
public:
int i;
};
//
Inherit base as virtual.
class
derived1 : virtual public base {
public:
int j;
};
//
Inherit base as virtual here, too.
class
derived2 : virtual public base {
public:
int k;
};
/*
Here, derived3 inherits both derived1 and derived 2.
However, only one copy of base is present.
*/
class
derived3 : public derived1, public derived2
{
public:
int product()
{ return i * j * k; }
};
void main()
{
derived3 ob;
ob.i=10;
// unambiguous because only one copy present
ob.j=3;
ob.k=5;
cout << "Product
is " <<ob.product() << '\n';
}
|