You are on page 1of 93

 

Inheritance 
First Lecture 
Date: 03/05/2017 

Introduction 
● There are some important concepts that we must talk about when discussing 
inheritance 

○ Base Class: A class from which we inherit (Animals is base for birds, and 
Birds is base for Ducks). 

○ Derived Class: A class which inherits from a base class(Birds is derived 


from Animals, and Ducks is derived from Birds). 

 

 

General Form for Inheritance in C++ 


class derived class name: access type base class name 

// body of class 

}; 

Protected data members in a class 


● Protected data members are one of the three data members in a class (the other 
two being private and public) 
● On the surface it behaves exactly like private data members, but like we are going 
to see later, they are very beneficial when dealing with inheritance in classes. 

 

 

#include <iostream> 

using namespace std; 

class test 

private: int i; 

protected: int j; 

public: int k; 

void print(){ cout << i << j << k; } 

}; 

int main() 

test x; 

cin >> x.i; // this returns error, since i is private 

cin >> x.j; // this returns error, since j is protected 

cin >> x.k; 

return 0; 

As we can see, both i and j cannot be accessed from outside the class(in the case of i is 
private, and j is protected). 

 

 

How To Use Inheritance 


Just like the data members in classes, there are 3 types of access for classes(Public, 
Private and Protected). 

Each one of them affects how we data members are accessed. 

We will use a table to keep track of how each one of them operate(and we will update it 
as we go along). 

 
  Base members access type 

Inheritance access type  Private  Protected  Public 

Private       

Protected       

Public       
● Members of base class will become members of derived class 

For example: 

#include <iostream>  

using namespace std; 

class base 

private : int i, j; 

public: 

void set_data (int a, int b){ i = a; b = j; } 

void print (){ cout << i << j << endl ;} 

}; 

 

 

class derived : ____ base 

private : int k; 

public: 

void set_k (int a){ k = a;} 

void print_k (){ cout << k << endl ;} 

}; 

● Access status of base class members is determined by inheritance access type 


(Public, Protected, Private). 
● All private in base are members of derived but are not accessible by members of 
derived class (Inherited but hidden), to access them, we need to use public 
functions from base class(print function in our example). 

 

 
● In the previous example both i and j are private in base and thus cannot be 
accessed from derived members. 

We can now update our table 


  Base members access type 

Inheritance access type  Private  Protected  Public 

Private  Not accessible     

Protected  Not accessible     

Public  Not accessible     

● Public access type means that public members of base class become public in 
derived, while protected in base will become protected in derived. 

For example: 

#include <iostream>  

using namespace std; 

class base 

private : int i, j; 

public: 

void set_data (int a, int b){ i = a; b = j; } 

void print (){ cout << i << j << endl ;} 

}; 

class derived : public base 

private : int k; 

public: 

void set_k (int a){ k = a;} 

void print_k (){ cout << k << endl ;} 

 

 

}; 

int main () 

base x; derived y; 

x.set_data (1, 2); 

x.print (); 

y.set_k (3); 

y.print (); // returns rubbish 

return 0; 

Notice that y.print() will print rubbish to the screen, since y can’t access i, j(they are 
hidden). Our data members will look like this: 

 

 

And our table will be updated to look like this: 

 
  Base members access type 

Inheritance access type  Private  Protected  Public 

Private  Not accessible     

Protected  Not accessible     

Public  Not accessible  Protected  Public 

● Using private access type, all public and protected data members of base will 
become private in derived(and thus not accessible). 
● Using protected inheritance access type, all public and protected members of 
base becomes protected members of class derived. 

Our data members will be:

 

 

And our table will be updated to become: 

 
  Base members access type 

Inheritance access type  Private  Protected  Public 

Private  Not accessible  Private  Private 

Protected  Not accessible  Protected  Protected 

Public  Not accessible  Protected  Public 

HomeWork 
Q:Write a program that has two classes (Father and Son), 
Father has the following data types(f_id, f_age, set_f, print_f), 
while Son has(s_id, s_age, set_s, print_s). And then test the 9 
probabilities in the table above. 

 
 

OOP 
Inheritance Types 

Date: 12/03/2017 

Inheritance Types 
● There are 5 types of inheritance in C++ language 
1. Single Inheritance 
2. Multi-Level Inheritance 
3. Hierarchical Inheritance 
4. Multiple Inheritance 
5. Hybrid Inheritance 

We will take a look on each one of them. 

 

 

1. Single Inheritance 
● It’s the type that we have been using all along and it looks something like this: 

Example: 

#include <iostream>  

using namespace std; 

class First 

private:  

int f_private;  

 

 

protected:  

int f_protected;  

public: 

int f_public;  

void read_f () 

cin >> f_private >> f_protected >> f_public;  

}   

}; 

class Second : public First 

private:  

int s_private;  

protected:  

int s_protected;  

public: 

int s_public;  

void read_s () 

cin >> s_private >> s_protected >> s_public;  

}; 

int main () 

 

 

First f; 

Second s; 

f.f_private = 3; // Error 

f.f_protected = 3; // Error 

f.f_public = 3; // Can be used 

f.read_f (); // Can be used 

s.s_private = 4; // Error 

s.s_protected = 4; // Error 

s.s_public = 4; // Can be used 

s.read_f (); // Can be used 

s.read_s (); // Can be used 

s.f_private = 5; // Error 

s.f_protected = 5; // Error 

s.f_public = 5; // Can be used 

return 0; 

 

 

Their trace looks like this: 

  

 
 

 

 

2. Multi-Level Inheritance 
● This type of inheritance is the same as the last one except the fact that it 
involves more than two classes(hence we call it multi level). 

● It looks like this: 

Example: 

#include <iostream>  

using namespace std; 

class First 

private:  

int f_private;  

protected:  

 

 

int f_protected;  

public: 

int f_public;  

void read_f () 

cin >> f_private >> f_protected >> f_public;  

}; 

class Second : public First 

private:  

int s_private;  

protected:  

int s_protected;  

public: 

int s_public;  

void read_s () 

cin >> s_private >> s_protected >> s_public;  

}; 

class Thrid : public Second 

private:  

 

 

int th_private;  

protected:  

int th_protected;  

public: 

int th_public;  

void read_th () 

cin >> th_private >> th_protected >> th_public;  

}; 

int main () 

First f; 

Second s; 

Third th; 

f.f_private = 3; // Error 

f.f_protected = 3; // Error 

f.f_public = 3; // Can be used 

f.read_f (); // Can be used 

s.s_private = 4; // Error 

s.s_protected = 4; // Error 

s.s_public = 4; // Can be used 

s.read_f (); // Can be used 

s.read_s (); // Can be used 

 

 

s.f_private = 5; // Error 

s.f_protected = 5; // Error 

s.f_public = 5; // Can be used 

th.th_private = 6; // Error 

th.th_protected = 6; // Error 

th.th_public = 6; // Can be used 

th.read_th (); // Can be used  

return 0; 

 
10 
 

And the trace looks like this: 

 
11 
 

3. Hierarchical Inheritance 
● In this type two classes(siblings) both inherit from one class (father) 

● This type of inheritance looks like this: 

Example: 

#include <iostream>  

using namespace std; 

class Father 

private:  

int f_private;  

protected:  

int f_protected;  

public: 

int f_public;  

 
12 
 

void read_f () 

cin >> f_private >> f_protected >> f_public;  

}; 

class Son : public Father 

private:  

int s_private;  

protected:  

int s_protected;  

public: 

int s_public;  

void read_s () 

cin >> s_private >> s_protected >> s_public;  

}; 

class Daughter : public Father 

private:  

int d_private;  

protected:  

int d_protected;  

 
13 
 

public: 

int d_public;  

void read_d () 

cin >> d_private >> d_protected >> d_public;  

int main () 

Father f; 

Son s; 

Daughter d; 

f.f_private = 5; // Error 

f.f_protected = 5; // Error 

f.f_public = 5; // Can be used 

f.read_f (); // Can be used 

s.s_private = 6; // Error 

s.f_private = 6; // Error 

s.s_protected = 6; // Error 

s.f_protected = 6; // Error 

s.s_public = 6; // Can be used 

s.f_public = 6; // Can be used 

s.read_s (); // Can be used 

s.read_f (); // Can be used 

 
14 
 

d.d_private = 7; // Error 

d.f_private = 7; // Error 

d.d_protected = 7; // Error 

d.f_protected = 7; // Error 

d.d_public = 7; // Can be used 

d.f_public = 7; // Can be used 

d.read_d (); // Can be used 

d.read_f (); // Can be used  

return 0; 

The trace will look like this: 

 
15 
 

4. Multiple Inheritance 
● In this type of inheritance a class inherits from 2 or more classes. 
● This type of inheritance looks like this: 

Example: 

#include <iostream>  

using namespace std; 

class Father 

private:  

int f_private;  

protected:  

int f_protected;  

public: 

int f_public;  

 
16 
 

void read_f () 

cin >> f_private >> f_protected >> f_public;  

}; 

class Mother 

private:  

int m_private;  

protected:  

int m_protected;  

public: 

int m_public;  

void read_m () 

cin >> m_private >> m_protected >> m_public;  

}; 

class Son : public Father , public Mother 

private:  

int s_private;  

protected:  

int s_protected;  

 
17 
 

public: 

int s_public;  

void read_s () 

cin >> s_private >> s_protected >> s_public;  

}; 

int main () 

Father f; 

Mother m; 

Son s; 

f.f_private = 2; // Error 

f.f_protected = 2; // Error 

f.f_public = 2; // Can be used 

f.read_f (); // Can be used 

m.m_private = 3; // Error 

m.m_protected = 3; // Error 

m.m_public = 3; // Can be used 

m.read_m (); // Can be used 

s.s_private = 4; // Error 

s.s_protected = 4; // Error 

s.s_public = 4; // Can be used 

s.read_s (); // Can be used 

 
18 
 

s.f_private = 2; // Error 

s.f_protected = 2; // Error 

s.f_public = 2; // Can be used 

s.read_f (); // Can be used 

s.m_private = 2; // Error 

s.m_protected = 2; // Error 

s.m_public = 2; // Can be used 

s.read_m (); // Can be used  

return 0; 

 
19 
 

The trace will be: 

 
20 
 

5. Hybrid Inheritance 
● This type combine all the previous types in different ways 
● This type can look like this: 

This type will be discussed in more details in the upcoming lectures. 

 
21 
 

HomeWork: Write a program that has a base class 


(Father) with the following informations {f_id, f_age} 
as data members, and derived classes (Son, Daughter) 
that have the following informations {s_id, s_age} and 
{d_id, d_age} respectively. Make Son and Daughter 
both inherit from Father. And then test the cases 
where the inheritance type is Public, Protected and 
Private. 

 
 

Inheritance 
Lecture 3: Example About Inheritance 

Date: 19/03/2017 
Q/ Consider the following program 
#include <iostream>  

using namespace std; 

class One { 

int i; 

void read () { cin >> i; } 

public : void read_one () { read (); } 

}; 

class Two : protected one { 

int j; 

public: 

void reading () { read (); } 

void read_two () { read_one (); } 

}; 

 

 

int main () 

One x; Two y; 

x.read (); 

x.read_one (); 

x.read_two (); 

y.read_one (); 

y.reading (); 

return 0; 

1. Determine the members of each class 


2. Determine errors 
3. What members are accessible by the function reading? 
4. What members are accessible by an object of type two? 

 

 

Answer: 

1. We can trace the program

 
2. The errors that will be produced are the following: 

x.read() → Because read() is Private 

x.read_two() → Because read_two() is NOT a member. 

y.read_one() → Because read_one() is Protected and can NOT be used outside of   

the object. 

3. The following members are all accessible by the function reading 


● j  
● read_one() 
● read_two() 
4. The following members are accessible to an object of type two 
● reading() 
● read_two() 

 

 

Q/ Add code to assign a value to each of R’s data members 


class P { 

int x, y; 

}; 

class Q { 

protected:  

float a, b; 

}; 

class R: public P, protected Q { 

}; 

Answer: 

The program has to be changed to be able to assign each value 

class P { 

int x, y; 

public: 

void set () 

x = 0; 

y = 0; 

}; 

class Q { 

protected:  

 

 

float a, b; 

}; 

class R: public P, protected Q { 

public: 

void assign () 

set (); // Because x and y are private so we need a public 


function to access them 

a = 0; 

b = 0; 

}; 

Q/ Consider the following segment of code 


class AB { 

int i, j; 

}; 

class DE { 

int k; 

}; 

class GH { 

int m;}; 

 

 

Add required code to: 

1. DE may access i and j 


2. GH may access m and k only 

Without using Public data type 

And the inheritance is defined like so: 

Answer: 

1. The code will become 

class AB { 

protected:  

  int x, y; 

}; 

class DE: public AB { 

  int k;} 

 

 

2. The code will become 

class AB { 

  int i, j; 

}; 

class DE: (public or protected or private ) AB { 

protected:  

int k; 

}; 

class GH: public DE { 

  int m; 

}; 

Q/ Consider the following information about 3 classes 

Store → Private data members st_no, city 

Group → data members g_type 

Item →  data members code, price, num 


And Group inherits Store(public), Item inherits Group(public) 

Do the following: 

1. Declare an object of type item, reading its data members. 


2. Write a member function(check) in class item that returns 1 if two items are in 
the same store 

 

 

Answer: 

1. Our trace looks something like this 

 

 

And to access all these data members we need to write the following code: 

#include <iostream>  

using namespace std; 

class Store { 

private:  

int st_no , city; 

public: 

void read_store (int s, int c) 

st_no = s; 

city = c; 

}; 

class Group : public Store { 

private:  

int g_type; 

public: 

void read_group (int g) 

g_type = g; 

}; 

class Item : public Group { 

private:  

 
10 
 

int code , price , num; 

public: 

void read_item (int c, int p, int n, int g, int s, int ci) 

read_store (s, ci); 

read_group (g); 

code = c; 

price = p; 

num = n; 

}; 

int main () 

Item x; 

x.read_item (1, 2, 3, 4, 5, 6); 

return 0; 

2. The code is: 

#include <iostream>  

using namespace std; 

class Store { 

private:  

int st_no , city; 

 
11 
 

public: 

int ret_sn () 

return st_no; 

int ret_city () 

return city; 

}; 

class Group : public Store { 

private:  

int g_type; 

}; 

class Item : public Group { 

private:  

int code , price , num; 

public: 

int check (Item x) 

if (ret_sn () == x.ret_sn () && ret_city () == x.ret_city ()) 

return 1; 

return 0; 

 
12 
 

}; 

int main () 

Item x; 

x.check (x); 

return 0; 

 
 

Inheritance 
By: Aws Al-Taee 
Lecture 4: Hybrid Inheritance  

&  

Constructor and Destructors in Inheritance 

Date: 26/03/2017 

Hybrid Inheritance 
● This is the last type of inheritance in C++ language 

● It combines between Hierarchical and Multiple Inheritance 

● It looks like this: 

 

 

Example:  

#include <iostream>  

using namespace std; 

class A { 

protected:  

int i; 

}; 

class B: public A { 

protected:  

int j; 

}; 

class C: public A { 

protected:  

int k; 

 

 

}; 

class D: public B, public C { 

int l; 

public: 

void read () 

cin >> i >> j >> k >> l; 

}; 

The trace of the program trace will look like this: 

 

 

As we can notice, there are two i data members in the class D, and this will create a 
problem( The compiler will complain of an ambiguity problem), as the compiler doesn’t 
know which i to use ( the one inherited from B or the one inherited from C ). This is 
called the diamond problem. 

Solving the Diamond Problem 


Diamond problem can be solved in 2 ways: 

1. Scope Resolution Operator( This is Done Manually ) 

This method is used when we want to preserve multiple versions of data 


members. 

Example ( Notice function read in class D ): 

#include <iostream>  

using namespace std; 

class A { 

protected:  

int i; 

}; 

class B: public A { 

protected:  

int j; 

}; 

class C: public A { 

protected:  

int k; 

}; 

 

 

class D: public B, public C { 

int l; 

public: 

void read () 

cin >> B::i >> C::i >> j >> k >> l; 

}; 

2. Virtual Inheritance: This is done by adding virtual keyword to both B and C 


classes, doing this will eliminate all duplicates, and thus only one i data member 
will be inherited by class D. 

Example ( Notice function read in class D ) :  

#include <iostream>  

using namespace std; 

class A { 

protected:  

int i; 

}; 

class B: public virtual A { 

protected:  

int j; 

}; 

class C: public virtual A { 

protected:  

 

 

int k; 

}; 

class D: public B, public C { 

int l; 

public: 

void read () 

cin >> i >> j >> k >> l; 

}; 

Constructor and Destructors within Inheritance 


● Constructors and Destructors are not inherited by the derived class ( but they are 
executed when an object of class derived is created or destroyed ). 

● The order of execution of Constructors depends on the type of Constructor ( 


Whether it is parameterized or not ). 

Order of Execution 
There are two order of execution for Constructors ( depending on the availability of 
parameters) and one order of execution for Destructors ( Since Destructors don’t have 
any parameters ). 

1. Default ( Without parameters ) 

In this type the order of execution for object creation is: 

 

 

➔ Base class Constructor ( If any is found ). 


➔ Derived class Constructor ( if any is found ). 

And the order of execution for object destruction is: 

➔ Derived class Destructor ( If any is found ). 


➔ Base class Destructor ( If any is found ). 

Example:  

#include <iostream>  

using namespace std; 

class A { 

protected:  

int i; 

public: 

A() 

cout << "Constructor A" << endl; 

cout << "Enter value of i:"; 

cin >> i; 

~A() 

cout << "Destructor A, i = " << i << endl; 

}; 

 

 

class B: public A { 

public: 

B() 

cout << "Constructor B" << endl; 

cout << "Enter value of j:"; 

cin >> j; 

~B() 

cout << "Destructor B, j = " << j << endl; 

}; 

int main () 

A x; 

B y; 

cout << "Inside Main" << endl; 

return 0; 

 

 

The execution screen will look like this:  

In case of multi-level inheritance: Constructors are called in order of derivation ( from 


top to bottom ), Destructors are in reverse order 

Example: 

#include <iostream>  

using namespace std; 

 
10 
 

class A { 

protected:  

int i; 

public: 

A() 

cout << "Constructor A" << endl; 

cout << "Enter value of i:"; 

cin >> i; 

~A() 

cout << "Destructor A, i = " << i << endl; 

}; 

class B: public A { 

public: 

B() 

cout << "Constructor B" << endl; 

cout << "Enter value of j:"; 

cin >> j; 

 
11 
 

~B() 

cout << "Destructor B, j = " << j << endl; 

}; 

class C: public B { 

int k; 

public: 

C() 

cout << "Constructor C" << endl; 

cout << "Enter value of k:"; 

cin >> k; 

~C() 

cout << "Destructor C, k = " << k << endl; 

}; 

 
12 
 

int main () 

A x; 

B y; 

C z; 

cout << "Inside Main" << endl; 

return 0; 

The execution screen will look like this: 

 
13 
 

 
14 
 

In case of multiple inheritance, constructors are called from left to right as specified in 
inheritance list, Destructors in reverse order. 

Example: 

#include <iostream>  

using namespace std; 

class A { 

protected:  

int i; 

public: 

A() 

cout << "Constructor A" << endl; 

cout << "Enter i:"; 

cin >> i; 

~A() 

 
15 
 

cout << "Destructor A, i = " << i << endl; 

}; 

class B { 

protected:  

int j; 

public: 

B() 

cout << "Constructor B" << endl; 

cout << "Enter j:"; 

cin >> j; 

~B() 

cout << "Destructor B, j = " << j << endl; 

}; 

class C: public A, public B { 

int k; 

 
16 
 

public: 

C() 

cout << "Constructor C" << endl; 

cout << "Enter k:"; 

cin >> k; 

~C() 

cout << "Destructor C, k = " << k << endl; 

}; 

int main () 

C x; 

cout << "Inside Main" << endl; 

return 0; 

 
17 
 

Notice that C inherits A before B and so our execution screen will look like this: 

Example: 

#include <iostream>  

using namespace std; 

class A { 

protected:  

int i; 

public: 

A() 

cout << "Constructor A" << endl; 

 
18 
 

cout << "Enter i:"; 

cin >> i; 

~A() 

cout << "Destructor A, i = " << i << endl; 

}; 

class B { 

protected:  

int j; 

public: 

B() 

cout << "Constructor B" << endl; 

cout << "Enter j:"; 

cin >> j; 

~B() 

cout << "Destructor B, j = " << j << endl; 

 
19 
 

}; 

class C: public B, public A { 

int k; 

public: 

C() 

cout << "Constructor C" << endl; 

cout << "Enter k:"; 

cin >> k; 

~C() 

cout << "Destructor C, k = " << k << endl; 

}; 

int main () 

C x; 

cout << "Inside Main" << endl; 

 
20 
 

return 0; 

In this example C inherits B before A, the execution screen will be: 

2. The second is parameterized constructor, which will be discussed in details later. 

 
 

Inheritance 
By: Aws Al-Taee 
Lecture 5: Parameterized Constructors in Inheritance 

Date: 02/04/2017 

Parameterized Constructors 
● This is the second type of constructors in inheritance. 

● To use a specific constructor, we need to specify which one we need to call 

For example: 

#include <iostream>  

using namespace std; 

class Base 

public: 

Base () 

 

 

cout << "Base Constructor" << endl; 

Base ( int j ) 

cout << "Base Constructor " << j << endl; 

~Base () 

cout << "Base Destructor" << endl; 

}; 

class Derived1 : public Base 

public: 

Derived1 ( int i ) 

cout << "Derived1 Constructor " << i << endl; 

}; 

int main () 

 

 

Derived1 D1(1); 

return 0; 

This code will generate the following output: 

Notice that we have 2 constructors in class Base, but only one of them was used and 
that’s because the first one is the default one, so it will be the one to be used. To use the 
second constructor of class Base, we need to specify it in the constructor of class 
Derived1 like so: 

Derived1 ( int i ) : Base ( i ) 

And the full program is:  

#include <iostream>  

using namespace std; 

class Base 

public: 

Base () 

cout << "Base Constructor" << endl; 

 

 

Base ( int j ) 

cout << "Base Constructor " << j << endl; 

~Base () 

cout << "Base Destructor" << endl; 

}; 

class Derived1 : public Base 

public: 

Derived1 ( int i ) : Base ( i ) 

cout << "Derived1 Constructor " << i << endl; 

}; 

int main () 

 

 

Derived1 D1(1); 

return 0; 

This will generate the following output: 

We can also have more than one constructor in class Derived1 and each one of those 
constructors call a different constructor from class Base. 

For example: 

#include <iostream>  

using namespace std; 

class Base 

public: 

Base () 

cout << "Base Constructor" << endl; 

 

 

Base ( int j ) 

cout << "Base Constructor " << j << endl; 

~Base () 

cout << "Base Destructor" << endl; 

}; 

class Derived1 : public Base 

public: 

Derived1 ( int i ) 

cout << "Derived1 Constructor " << i << endl; 

Derived1 ( int i, int j ) : Base (i) 

cout << "Derived1 Constructor " << j << endl; 

 

 

~Derived1 () 

cout << "Derived1 Destructor" << endl; 

}; 

int main () 

Derived1 D1(1); 

Derived1 D2(2, 3); 

return 0; 

Which generates the output: 

 
 

Pointers 
Date: 29/04/2017 

What are pointers? 


❖ Pointers are special data types, just like int, float and char  

➢ They only different between pointers and other types of data types are that 
pointers hold the memory address of another variable instead of an actual 
value. 

Notice in the image above, we have a variable X of type integer and it has a value 
of 70 and an address of 2001, while PTR is a variable of type pointer and it has a 
value 2001 which happens to be the value of X. 

 

 

How To De ne Pointers? 
❖ To define pointers in c++ we follow the following formula: 

➢ <pointer type> *<pointer name> 

■ Pointer type refers to the type of data the pointer is pointing to. 

■ * signify that we are defining a pointer 

■ Pointer name is the identifier we use for our pointer. 

Example: 

#include <iostream>  

using namespace std; 

int main () 

int x = 5; 

int *xPtr; 

   

xPtr = &x; 

cout << xPtr << endl; 

return 0; 

We defined x as an integer and xPtr as a pointer. Next we used the command   

xPtr = &x;  

Which tells the compiler to let xPtr point at the address of x. 

We use (&) which means address of. 

 

 

cout << xPtr << endl; Will print the address saved in xPtr (in my case it was 
0x7ffe305099a4. But it will be different every time run the program). 

 
 

 

 

Changing values of variables using pointers 


❖ We can change the value of a variable from its pointer like so: 

➢ Example: 

#include <iostream>  

using namespace std; 

int main () 

int x = 5; 

cout << "x = " << x << endl; 

   

int *xPtr = &x; 

*xPtr = 100; 

cout << "x = " << x << endl; 

return 0; 

Running this we will see that the value of x will change from 5 to 100, although we never 
used x = 100. 

This is because we used the ( * operator ). 

❖ * operator works in 2 ways depending on where we use it. 

➢ If we use it in a definition statement(defining a variable) then it means we 


are defining a pointer. 

 

 

➢ If we use it in a normal statement then it means give me the variable that 


this pointer is pointing to.  

In this case *xPtr = 100; will be converted to x = 100 

 
 

 

 

De ning pointers using new keyword 


❖ We usually use the new keyword when defining pointers for arrays or objects. 

➢ Example:  

#include <iostream>  

using namespace std; 

int main () 

char *arrPtr = new char [5]; 

arrPtr [1] = 'A'; 

return 0; 

This will create an array of type char, that have 5 elements. Notice that the array does 
not have any name. It does have, however, a pointer arrPtr pointing to its first 
element(the pointer always points to the first element). 

 

 

Example: 

#include <iostream>  

using namespace std; 

int main () 

char arr [5]; 

char *arrPtr = arr; // We can also use char *arrPtr = &arr[0] 

   

return 0; 

Notice how in the statement ( char *arrPtr = arr;) we didn’t use the ( & operator ) 
because the name of the array is in itself a pointer ( it points to the first element of the 
array).  

 

 

❖ We can use pointers to point to objects. 

➢ Example: 

#include <iostream>  

using namespace std; 

class Test { 

private:  

int i; 

public: 

void read () 

cout << "Enter:";  

cin >> i; 

void print () 

cout << "i = " << i << endl; 

}; 

int main () 

Test A; 

 

 

Test *ptr = new Test; 

A.read (); 

ptr -> read (); 

A.print (); 

ptr -> print (); 

return 0; 

Notice that ( A.read() and ptr -> read() are the same). We need to use the arrow ( → ) 
when we deal with pointers. 

Memory address of a pointer 


❖ Pointers also have memory address. 

Notice that zPtr is a pointer pointing to Z, but also have a memory address ( 40123 in 
this case). 

 
 

Pointers to Derived Classes 


Date: 01/05/2017 

Pointers to classes 
❖ Pointers to the base class are compatible with all classes derived from it. 

➢ We have to keep in mind that we can access data types inherited from 
base class when using a pointer to a derived class. 

Example: 

#include <iostream>  

using namespace std; 

class base{ 

private:  

int i; 

public: 

void print_data () 

 

 

cout << "i = " << i << endl; 

}; 

class derived : public base { 

private:  

int j; 

public: 

void print_data () 

cout << "j = " << j << endl; 

}; 

int main () 

base a, *b; 

derived c, *d; 

// Both of the bellow are acceptable  

b = &a; 

d = &c; 

// This is acceptable because because b is a base 

 

 

// and c is derived 

b = &c; 

   

// This is NOT acceptable because d is derived 

// while a is base 

d = &a; 

   

   

return 0; 

Using Data from pointers to classes 


❖ We can only use functions defined in the base class and not in the derived class. 

Example: 

#include <iostream>  

using namespace std; 

class base { 

private:  

int i = 10; 

public: 

void print_data () 

 

 

cout << "i = " << i << endl; 

}; 

class derived : public base { 

private:  

int j = 5; 

public: 

void print_data () 

cout << "j = " << j << endl; 

}; 

int main () 

base *a; 

derived b; 

a = &b; 

a -> print_data (); 

 

 

return 0; 

The output will be ( i = 10 ) instead of ( j = 5 ) and that’s because a does NOT recognize 
the print_data function of the derived class. 

 
 

Dynamic Binding  
&  
Operator Overloading 
Date: 29/05/2017 

Virtual Function 
● Virtual functions are used to allow us to use dynamic binding 

● The simple idea behind it is to define a base class, and then make other classes 
inherit from it. And then define a pointer to the base class, and make a new 
object from any of the children of that base class. 

● For dynamic binding we need 3 things: 

○ Inheritance 

○ Pointer of base type 

○ Virtual function 

Example: 

#include <iostream>  

 

 

using namespace std; 

class Shape 

protected:  

int width , length; 

public: 

void input (int x, int y) 

width = x; 

length = y; 

virtual int area () 

cout << "Shape class" << endl; 

   

}; 

 

 

class Rectangle : public Shape 

public: 

int area () 

cout << "Rectangle Area = " << width * length << endl; 

   

}; 

class Triangle : public Shape 

public: 

int area () 

cout << "Triangle Area = " << 0.5 * width * length << endl; 

   

}; 

 

 

class Circle : public Shape 

public: 

int area () 

cout << "Circle Area = " << 0.5 * length * length * 3.14 << endl; 

   

}; 

int main () 

Shape *s; 

int l, w; 

int choice; 

   

cout << "Choose from the following:" << endl << "1.Rectangle  
2.Triangle 3.Circle" << endl; 

cin >> choice; 

 

 

switch (choice ) { 

case 1: 

s = new Rectangle;  

cout << "Enter the width and height" << endl; 

cin >> w >> l; 

s -> input (w, l); 

s -> area (); 

break; 

case 2: 

s = new Triangle;  

cout << "Enter the base and height" << endl; 

cin >> w >> l; 

s -> input (w, l); 

s -> area (); 

break; 

case 3: 

s = new Circle; 

cout << "Enter the radius" << endl; 

cin >> l; 

 

 

s -> input (0, l); 

s -> area (); 

break; 

default:  

cout << "Not a valid choice" << endl; 

break; 

   

return 0; 

The classes looks like this: 

And this is what we call dynamic binding, the area function that the program calls, 
depends on what the user specifies and the compiler does not know which one to call 
until it is told by the user. 

 

 

We can use what is called Pure Virtual Functions in our base class like so: 

Change Shape class area definition from: 

virtual int area () 

{cout << "Shape class" << endl;}  

To: 

virtual int area () = 0; 

A simple trace of the program looks like this (User inputs are in white): 

 

 

Operator Overloading 
● C++ allows us to overload most operators in the language. 

● Overloading means giving an operator a different functionality 

○ For example: using ( ++ operator ) will increase a variable by 1, we can 


change its behaviour to change it by 2. 

● The general form for overloading an opera 

○ Return Type operator(Reserved word) symbol(parameters) { … body… } 

● We need to keep in mind that we can’t overload every operator(we can’t overload 
[. , * ?] 

● And the number of parameters stays the same 

○ For example: the operator ( ++ ) takes only one parameter, so when we 
overload it, we must provide only one parameter. 

Example: 

#include <iostream>  

using namespace std; 

class Rectangle  

int l, w; 

public: 

Rectangle ( int x, int y ) 

 

 

l = x; 

w = y; 

   

Rectangle operator + (Rectangle r) 

Rectangle r1(0, 0); 

r1.l = l + r.l; 

r1.w = w + r.w; 

return r1; 

bool operator == (Rectangle r) 

if ( l == r.l && w == r.w ) { 

return true; 

return false; 

void print_val () 

 
10 
 

cout << "Length = "<<l<<", width = "<<w<<" " << endl; 

   

}; 

int main () 

Rectangle p(5, 5), q(6, 6); 

Rectangle r(0, 0); 

r = p + q; 

r.print_val (); 

if (p == q) { 

cout << "Equal" << endl; 

else { 

cout << "Not Equal" << endl; 

return 0; 

You might also like