|
C++ Programming Tutorial IV
Inheritance |
class derived_class_name:access_specifier base_class_name {
// body of class
};
- Inheritance allows hierarchical classifications.
- A class that is inherited is referred to as a base class.
- The class that does the inheriting is called the derived class.
- The class_specifier can be public, private, or
protected.
- A derived class can be used as a base class for another derived class
(multiple inheritance).
- Recall a class declaration:
class class_name {
private data and functions
access-specifier:
data and functions
access-specifier:
data and functions
...
...
access-specifier:
data and functions
} object-list;
Base Class Access Control, Public
#include <iostream.h>
class base {
int i, j;
public:
void set(int a, int b) {i=a; j=b;}
void show() {cout << i << " " << j << "\n";}
};
class derived : public base {
int k;
public:
derived(int x) {k=x;}
void showk() {cout << k << "\n";}
};
main()
{
derived ob(3);
ob.set(1, 2); // access member of base
ob.show(); // access member of base
ob.showk(); // uses member of derived class
return 0;
}
- When the access specifier for a base class is public, all public
members of the base become public members of the derived class; and
- All protected members of the base become protected members of the derived
class.
- The base class' private elements remain private to the base and are not
accessible by members of the derived class.
Base Class Access Control, private
// This program won't compile.
#include <iostream.h>
class base {
int i, j;
public:
void set(int a, int b) {i=a; j=b;}
void show() {cout << i << " " << j << "\n";}
};
// Public elements of base are private in derived.
class derived : private base {
int k;
public:
derived(int x) {k=x;}
void showk() {cout << k << "\n";}
};
main()
{
derived ob(3);
ob.set(1, 2); // error, can't access set()
ob.show(); // error, can't access show()
return 0;
}
- When the base class is inherited by using the private
access-specifier, all public and protected members of the base class become
private members of the derived class.
- This means that they are still accessible by members of the derived class
but cannot be accessed by parts of your program that are not members of either
the base or derived class.
Protected Class Members
class base {
protected:
int i, j; // private to base, but accessible by derived
public:
void set(int a, int b) {i=a; j=b;}
void show() {cout << i << " " << j << "\n";}
};
- When a class member is declared as protected, that member is not
accessible by other, non-member elements of the program just like
private members.
Inheriting Protected Members, public
#include <iostream.h>
class base {
protected:
int i, j; // private to base, but accessible by derived
public:
void set(int a, int b) {i=a; j=b;}
void show() {cout << i << " " << j << "\n";}
};
class derived : public base {
int k;
public:
// derived may access base's i and j
void setk() {k=i*j;}
void showk() {cout << k << "\n";}
};
main()
{
derived ob;
ob.set(2, 3); // OK, known to derived
ob.show(); // OK, know to derived
ob.setk();
ob.showk();
return 0;
}
- If the base class is inherited as public, then the base class'
protected members become protected members of the derived class and are,
therefore, accessible by the derived class.
Inheriting Protected Members, protected
#include <iostream.h>
class base {
protected:
int i, j; // private to base, but accessible by derived
public:
void setij(int a, int b) {i=a; j=b;}
void showij() {cout << i << " " << j << "\n";}
};
// Inherit base as protected.
class derived : protected base {
int k;
public:
// derived may access base's i and j and setij().
void setk() {
setij(10, 12);
k = i*j;
}
void showall() {
cout << k << " ";
showij();
}
};
main()
{
derived ob;
// ob.setij(2, 3); // illegal, setij() is protected member of derived
ob.setk(); // OK, public member of derived
ob.showall(); // OK, public member of derived
// ob.showij(); // illegal, showij() is protected member of derived
return 0;
}
- When the base class is inherited as protected, all public and
protected members of the base class become protected members of the derived
class.
Inheriting Multiple Base Classes
#include <iostream.h>
class base1 {
protected:
int x;
public:
void showx() {cout << x << "\n";}
};
class base2 {
protected:
int y;
public:
void showy() {cout << y << "\n";}
};
// Inherit multiple base classes.
class derived : public base1, public base2 {
public:
void set(int i, int j) {x=i; y=j;}
};
main()
{
derived ob;
ob.set(10, 20); // provided by derived
ob.showx(); // from base 1
ob.showy(); // from base 2
return 0;
}
- To inherit more than one base class, use a common-separated list.
- Be sure to use an access specifier for each base inherited.
Summary of Inheritance Access Control
|
|
Inheritance Control, (Derived class) |
|
|
public |
private |
protected |
Access Control, (Base Class) |
public |
public |
private |
protected |
private |
Not accessible |
Not accessible |
Not accessible |
protected |
protected |
private |
protected |
Inheritance - When Constructors and Destructors are Executed?
#include <iostream.h>
class base {
public:
base() {cout << "Constructing base\n";}
~base() {cout << "Destructing base\n";}
};
class derived1 : public base {
public:
derived1() {cout << "Constructing derived1\n";}
~derived1() {cout << "Destructing derived1\n";}
};
class derived2 : public base {
public:
derived2() {cout << "Constructing derived2\n";}
~derived2() {cout << "Destructing derived2\n";}
};
main()
{
derived2 ob;
// construct and destruct ob
return 0;
}
|
|
Output:
Constructing base
Constructing derived1
Constructing derived2
Destructing derived2
Destructing derived1
Destructing base
|
- When an object of a derived class is created, if the base class contains a
constructor, it will be called first, followed by the derived class'
constructor.
- When a derived object is destroyed, its destructor is called first,
followed by the base class' destructor, if it exists.
- Put differently, constructor functions are executed in their order of
derivation.
- Destructor functions are executed in reverse order of derivation.
- In case of multiple inheritance, the general rule applies:
Constructors are called in order of derivation, destructors in reverse
order.
Passing Parameters to Base Class Constructors?
#include <iostream.h>
class base {
protected:
int i;
public:
base(int x) {
i=x;
cout << "Constructing base\n";
}
~base() {cout << "Destructing base\n";}
};
class derived:public base {
int j;
public:
// derived uses x; y is passed along to base.
derived(int x, int y): base(y) {
j=x;
cout << "Constructing derived\n";
}
~derived() {cout << "Destructing derived\n";}
void show() {cout << i << " " << j << "\n";}
};
main()
{
derived ob(3, 4);
ob.show(); // displays 4 3
return 0;
}
|
|
Output:
derived-constructor(arg-list): base1(arg-list),
base2(arg-list),
...
...
baseN(arg-list)
{
// body of derived constructor
}
|
- Use an expanded form of the derived class' constructor declaration that
passes along arguments to one or more base class constructors.
- Even if a derived class' constructor does not use any arguments, it will
still need to declare one or more if the base class takes one or more
arguments.
- An argument that is passed along to a base class does not preclude its use
by the derived class as well.
End of Tutorial IV
|