Object Oriented
Programming using C++
By Mohamed Gamal
© Mohamed Gamal 2024
The topics of today’s lecture:
Agenda
#include <iostream>
#include <string>
using namespace std;
class Car {
private:
string make;
double price;
int year;
public:
Car() : make(""), price(0.0), year(0)
{ }
Car(string carMake, double carPrice, int carYear)
{
make = carMake;
price = carPrice;
year = carYear;
}
void setDetails() {
cout << "Enter car make: ";
getline(cin, make);
cout << "Enter car price: ";
cin >> price;
cout << "Enter production year: ";
cin >> year;
}
void displayDetails() const {
cout << "Car Make (Company): " << make << endl;
cout << "Car Price: " << price << endl;
cout << "Car Year: " << year << endl;
}
};
int main() {
Car myCar;
// Get car details
myCar.setDetails();
// Show the car details
cout << "Car Details:n";
myCar.displayDetails();
return 0;
}
Example
Car Class
Inheritance in OOP
– Inheritance is probably the most powerful feature of object-oriented
programming, after classes themselves.
– Inheritance is the process of creating new classes, called derived classes, from
existing or base classes.
– The derived class inherits all the capabilities of the base class but can add
embellishments and refinements of its own.
– The main class remain unchanged.
– Inheritance allows code reusability.
#include <iostream>
using namespace std;
class Counter //base class
{
protected: //NOTE: not private
unsigned int count; //count
public:
Counter() : count(0) //no-arg constructor
{ }
Counter(int c) : count(c) //1-arg constructor
{ }
unsigned int get_count() const //return count
{
return count;
}
Counter operator ++ () //incr count (prefix)
{
return Counter(++count);
}
};
class CountDn : public Counter //derived class
{
public:
Counter operator -- () //decr count (prefix)
{
return Counter(--count);
}
};
int main()
{
CountDn c1; //c1 of class CountDn
cout << "c1 = " << c1.get_count() << endl; //display c1
++c1;
++c1;
++c1;
cout << "c1 = " << c1.get_count() << endl; //display it
--c1;
--c1;
cout << "c1 = " << c1.get_count() << endl; //display it
return 0;
}
Example
#include <iostream>
using namespace std;
// Base (Super) Class
class Shape
{
private:
int height;
int width;
public:
Shape() : height(0), width(0)
{ }
Shape(int h, int w) : height(h), width(w)
{ }
int getHeight() const {
return height;
}
int getWidth() const {
return width;
}
void printData() const {
cout << "Height: " << height << endl;
cout << "Width: " << width << endl;
}
};
// Dervied (Sub) Class
class Square : public Shape
{
public:
Square() : Shape()
{ }
Square(int s) : Shape(s, s)
{ }
int getArea() const {
return getHeight() * getWidth();
}
};
// Dervied (Sub) Class
class Rectangle : public Shape
{
public:
Rectangle() : Shape()
{ }
Rectangle(int h, int w) : Shape(h, w)
{ }
int getArea() const {
return getHeight() * getWidth();
}
};
int main()
{
Square s1(5);
Rectangle r1(7, 2);
cout << "Square Area: " << s1.getArea() << endl;
cout << "Rectangle Area: " << r1.getArea() << endl;
return 0;
}
Example
The protected Access Specifier
– A protected member can be accessed by member functions in its own
class or in any class derived from its own class.
– It can’t be accessed from functions outside these classes, such as main().
#include <iostream>
using namespace std;
class Counter
{
protected: //NOTE: not private
unsigned int count; //count
public:
Counter() : count(0) //constructor, no args
{ }
Counter(int c) : count(c) //constructor, one arg
{ }
unsigned int get_count() const //return count
{
return count;
}
Counter operator ++ () //incr count (prefix)
{
return Counter(++count);
}
};
class CountDn : public Counter
{
public:
CountDn() : Counter() //constructor, no args
{ }
CountDn(int c) : Counter(c) //constructor, 1 arg
{ }
CountDn operator -- () //decr count (prefix)
{
return CountDn(--count);
}
};
int main()
{
CountDn c1; //class CountDn
CountDn c2(100);
cout << "c1 = " << c1.get_count() << endl; //display
cout << "c2 = " << c2.get_count() << endl; //display
++c1; ++c1; ++c1; //increment c1
cout << "c1 = " << c1.get_count() << endl; //display it
--c2; --c2; //decrement c2
cout << "c2 = " << c2.get_count() << endl; //display it
CountDn c3 = --c2; //create c3 from c2
cout << "c3 = " << c3.get_count() << endl; //display c3
return 0;
}
Derived Class
Constructors
The CountDn() constructor calls
the Counter() constructor in the
base class.
#include <iostream>
#include <process.h> //for exit()
using namespace std;
class Stack
{
protected: //NOTE: can’t be private
enum { MAX = 3 }; //size of stack array
int st[MAX]; //stack: array of integers
int top; //index to top of stack
public:
Stack() : top(-1) //constructor
{ }
void push(int var) //put number on stack
{
st[++top] = var;
}
int pop() //take number off stack
{
return st[top--];
}
};
class Stack2 : public Stack
{
public:
void push(int var) //put number on stack
{
if (top >= MAX - 1) //error if stack full
{
cout << "nError: stack is full";
exit(1);
}
Stack::push(var); //call push() in Stack class
}
int pop() //take number off stack
{
if (top < 0) //error if stack empty
{
cout << "nError: stack is emptyn";
exit(1);
}
return Stack::pop(); //call pop() in Stack class
}
};
int main()
{
Stack2 s1;
s1.push(11); //push some values onto stack
s1.push(22);
s1.push(33);
cout << endl << s1.pop(); //pop some values from stack
cout << endl << s1.pop();
cout << endl << s1.pop();
cout << endl << s1.pop(); //oops, popped one too many...
return 0;
}
Overriding Member
Functions
#include <iostream>
using namespace std;
enum posneg { pos, neg }; //for sign in DistSign
class Distance
{
protected: //NOTE: can't be private
int feet;
float inches;
public:
Distance() : feet(0), inches(0.0)
{ }
Distance(int ft, float in) : feet(ft), inches(in)
{ }
void getdist() {
cout << "nEnter feet: "; cin >> feet;
cout << "Enter inches: "; cin >> inches;
}
void showdist() const {
cout << feet << "' - " << inches << '"';
}
};
class DistSign : public Distance //adds sign to Distance
{
private:
posneg sign; //sign is pos or neg
public:
DistSign() : Distance() //call base constructor
{
sign = pos; //set the sign to +
}
// 2- or 3-arg constructor
DistSign(int ft, float in, posneg sg = pos) : Distance(ft, in) //call base constructor
{
sign = sg; //set the sign
}
void getdist() //get length from user
{
Distance::getdist(); //call base getdist()
char ch; //get sign from user
cout << "Enter sign (+ or -): ";
cin >> ch;
sign = (ch == '+') ? pos : neg;
}
void showdist() const //display distance
{
cout << ((sign == pos) ? "(+)" : "(-)"); //show sign
Distance::showdist(); //ft and in
}
};
int main()
{
DistSign alpha; //no-arg constructor
alpha.getdist(); //get alpha from user
DistSign beta(11, 6.25); //2-arg constructor
DistSign gamma(100, 5.5, neg); //3-arg constructor
//display all distances
cout << "nalpha = ";
alpha.showdist();
cout << "nbeta = ";
beta.showdist();
cout << "ngamma = ";
gamma.showdist();
return 0;
}
Derived Class
Constructors
More Complex Example
Class Hierarchies
UML Class Diagram
#include <iostream>
using namespace std;
const int LEN = 80; //maximum length of names
class employee //employee class
{
private:
char name[LEN]; //employee name
unsigned long number; //employee number
public:
void getdata()
{
cout << "n Enter last name: "; cin >> name;
cout << " Enter number: "; cin >> number;
}
void putdata() const
{
cout << "n Name: " << name;
cout << "n Number: " << number;
}
};
class manager : public employee //management class
{
private:
char title[LEN]; //"vice-president" etc.
double dues; //golf club dues
public:
void getdata()
{
employee::getdata();
cout << " Enter title: "; cin >> title;
cout << " Enter golf club dues: "; cin >> dues;
}
void putdata() const
{
employee::putdata();
cout << "n Title: " << title;
cout << "n Golf club dues: " << dues;
}
};
class scientist : public employee //scientist class
{
private:
int pubs; //number of publications
public:
void getdata()
{
employee::getdata();
cout << " Enter number of pubs: "; cin >> pubs;
}
void putdata() const
{
employee::putdata();
cout << "n Number of publications: " << pubs;
}
};
class laborer : public employee //laborer class
{
};
int main()
{
manager m1;
scientist s1;
laborer l1;
//get data for several employees
cout << "nEnter data for manager 1";
m1.getdata();
cout << "nEnter data for scientist 1";
s1.getdata();
cout << "nEnter data for laborer 1";
l1.getdata();
//display data for several employees
cout << "nData on manager 1";
m1.putdata();
cout << "nData on scientist 1";
s1.putdata();
cout << "nData on laborer 1";
l1.putdata();
return 0;
}
Example
Class Hierarchies
#include <iostream>
using namespace std;
class A //base class
{
private:
int privdataA;
protected:
int protdataA;
public:
int pubdataA;
};
class B : public A //publicly-derived class
{
public:
void funct()
{
int a;
a = privdataA; //error: not accessible
a = protdataA; //OK
a = pubdataA; //OK
}
};
class C : private A //privately-derived class
{
public:
void funct()
{
int a;
a = privdataA; //error: not accessible
a = protdataA; //OK
a = pubdataA; //OK
}
};
int main()
{
int a;
B objB;
a = objB.privdataA; //error: not accessible
a = objB.protdataA; //error: not accessible
a = objB.pubdataA; //OK (A public to B)
C objC;
a = objC.privdataA; //error: not accessible
a = objC.protdataA; //error: not accessible
a = objC.pubdataA; //error: not accessible (A private to C)
return 0;
}
publicly- and privately-
derived classes
Multiple Inheritance
UML Class Diagram
class A // base class A
{ };
class B // base class B
{ };
class C : public A, public B // C is
derived from A and B
{ };
#include <iostream>
using namespace std;
const int LEN = 80; //maximum length of names
class student //educational background
{
private:
char school[LEN]; //name of school or university
char degree[LEN]; //highest degree earned
public:
void getedu()
{
cout << " Enter name of school or university: ";
cin >> school;
cout << " Enter highest degree earned (Highschool, Bachelor’s, Master’s, PhD): ";
cin >> degree;
}
void putedu() const
{
cout << "n School or university: " << school;
cout << "n Highest degree earned: " << degree;
}
};
class employee
{
private:
char name[LEN]; //employee name
unsigned long number; //employee number
public:
void getdata()
{
cout << "n Enter last name: "; cin >> name;
cout << " Enter number: "; cin >> number;
}
void putdata() const
{
cout << "n Name: " << name;
cout << "n Number: " << number;
}
};
class manager : private employee, private student //management
{
private:
char title[LEN]; //"vice-president" etc.
double dues; //golf club dues
public:
void getdata()
{
employee::getdata();
cout << " Enter title: "; cin >> title;
cout << " Enter golf club dues: "; cin >> dues;
student::getedu();
}
void putdata() const
{
employee::putdata();
cout << "n Title: " << title;
cout << "n Golf club dues: " << dues;
student::putedu();
}
};
class scientist : private employee, private student //scientist
{
private:
int pubs; //number of publications
public:
void getdata()
{
employee::getdata();
cout << " Enter number of pubs: "; cin >> pubs;
student::getedu();
}
void putdata() const
{
employee::putdata();
cout << "n Number of publications: " << pubs;
student::putedu();
}
};
class laborer : public employee //laborer
{ };
int main()
{
manager m1;
scientist s1;
laborer l1;
//get data for several employees
cout << "nEnter data for manager 1";
m1.getdata();
cout << "nEnter data for scientist 1";
s1.getdata();
cout << "nEnter data for laborer 1";
l1.getdata();
//display data for several employees
cout << "nData on manager 1";
m1.putdata();
cout << "nData on scientist 1";
s1.putdata();
cout << "nData on laborer 1";
l1.putdata();
return 0;
}
Example
private Derivation
– The manager and scientist classes in EMPMULT are privately derived from the
employee and student classes.
– There is no need to use public derivation because objects of manager and
scientist never call routines in the employee and student base classes.
– However, the laborer class must be publicly derived from employer, since it
has no member functions of its own and relies on those in employee.
#include <iostream>
#include <string>
using namespace std;
class Person
{
private:
string name;
int age;
public:
Person() : name(""), age(0)
{ }
Person(string n, int a) : name(n), age(a)
{ }
void getPerson() //get person from user
{
cout << "tEnter name: "; cin >> name;
cout << "tEnter age: "; cin >> age;
}
void showPerson() const //display type
{
cout << "tName: " << name << endl;
cout << "tAge: " << age << endl;
}
};
class Employee
{
private:
string ID;
double salary;
public:
Employee() : ID(""), salary(0.0)
{ }
Employee(string id, double s) : ID(id), salary(s)
{ }
void getEmployee() //get Employee from user
{
cout << "tEnter ID: "; cin >> ID;
cout << "tEnter salary: "; cin >> salary;
}
void showEmployee() const //display Employee
{
cout << "tID: " << ID << endl;
cout << "tSalary: " << salary << endl;
}
};
class Teacher : public Person, public Employee
{
private:
string rank;
public:
Teacher() : Person(), Employee(), rank("")
{ }
Teacher(string name, int age, string ID, double salary, string r)
: Person(name, age), Employee(ID, salary), rank(r)
{ }
void getTeacher()
{
Person::getPerson();
Employee::getEmployee();
cout << "tEnter rank: "; cin >> rank;
}
void showTeacher() const
{
Person::showPerson();
Employee::showEmployee();
cout << "trank: " << rank << endl;
}
};
int main()
{
Teacher t1;
cout << "Enter Teacher 1 data:nn";
t1.getTeacher();
Teacher t2("Ahmed", 38, "1234", 2500, "Excellent");
//display Teacher data
cout << "nnTeacher 1:n";
t1.showTeacher();
cout << "nnTeacher 2:n";
t2.showTeacher();
return 0;
}
Constructors in Multiple
Inheritance
#include <iostream>
using namespace std;
class A {
public:
void show() { cout << "Class An"; }
};
class B {
public:
void show() { cout << "Class Bn"; }
};
class C : public A, public B
{};
int main() {
C objC; //object of class C
// objC.show(); //ambiguous--will not compile
objC.A::show(); //OK
objC.B::show(); //OK
return 0;
}
Ambiguity in Multiple
Inheritance
1) Two base classes have functions
with the same name, while a class
derived from both base classes
has no function with this name.
How do objects of the derived
class access the correct base class
function?
#include <iostream>
using namespace std;
class A {
public:
void func();
};
class B : public A
{ };
class C : public A
{ };
class D : public B, public C
{ };
int main()
{
D objD;
objD.func(); //ambiguous: won’t compile
return 0;
}
Ambiguity in Multiple
Inheritance
2) Another kind of ambiguity arises
if you derive a class from two
classes that are each derived
from the same class.
This creates a diamond-shaped
inheritance tree.
#include <iostream>
#include <string>
using namespace std;
class student //educational background
{
private:
string school; //name of school or university
string degree; //highest degree earned
public:
void getedu()
{
cout << " Enter name of school or university: ";
cin >> school;
cout << " Enter highest degree earned (Highschool, Bachelor’s, Master’s, PhD): ";
cin >> degree;
}
void putedu() const
{
cout << "n School or university: " << school;
cout << "n Highest degree earned: " << degree;
}
};
class employee
{
private:
string name; //employee name
unsigned long number; //employee number
public:
void getdata()
{
cout << "n Enter last name: "; cin >> name;
cout << " Enter number: "; cin >> number;
}
void putdata() const
{
cout << "n Name: " << name;
cout << "n Number: " << number;
}
};
class manager //management
{
private:
string title; //"vice-president" etc.
double dues; //golf club dues
employee emp; //** object of class employee
student stu; //** object of class student
public:
void getdata()
{
emp.getdata();
cout << " Enter title: "; cin >> title;
cout << " Enter golf club dues: "; cin >> dues;
stu.getedu();
}
void putdata() const
{
emp.putdata();
cout << "n Title: " << title;
cout << "n Golf club dues: " << dues;
stu.putedu();
}
};
class scientist //scientist
{
private:
int pubs; //number of publications
employee emp; //** object of class employee
student stu; //** object of class student
public:
void getdata()
{
emp.getdata();
cout << " Enter number of pubs: "; cin >> pubs;
stu.getedu();
}
void putdata() const
{
emp.putdata();
cout << "n Number of publications: " << pubs;
stu.putedu();
}
};
class laborer //laborer
{
private:
employee emp; //object of class employee
public:
void getdata() {
emp.getdata();
}
void putdata() const {
emp.putdata();
}
};
int main()
{
manager m1;
scientist s1;
laborer l1;
//get data for several employees
cout << "nEnter data for manager 1";
m1.getdata();
cout << "nEnter data for scientist 1";
s1.getdata();
cout << "nEnter data for laborer 1";
l1.getdata();
//display data for several employees
cout << "nData on manager 1";
m1.putdata();
cout << "nData on scientist 1";
s1.putdata();
cout << "nData on laborer 1";
l1.putdata();
return 0;
}
Aggregation instead of
inheritance
2) Another kind of ambiguity arises
if you derive a class from two
classes that are each derived
from the same class.
This creates a diamond-shaped
inheritance tree.
End of lecture 3
ThankYou!

Object Oriented Programming (OOP) using C++ - Lecture 3

  • 1.
    Object Oriented Programming usingC++ By Mohamed Gamal © Mohamed Gamal 2024
  • 2.
    The topics oftoday’s lecture: Agenda
  • 4.
    #include <iostream> #include <string> usingnamespace std; class Car { private: string make; double price; int year; public: Car() : make(""), price(0.0), year(0) { } Car(string carMake, double carPrice, int carYear) { make = carMake; price = carPrice; year = carYear; } void setDetails() { cout << "Enter car make: "; getline(cin, make); cout << "Enter car price: "; cin >> price; cout << "Enter production year: "; cin >> year; } void displayDetails() const { cout << "Car Make (Company): " << make << endl; cout << "Car Price: " << price << endl; cout << "Car Year: " << year << endl; } }; int main() { Car myCar; // Get car details myCar.setDetails(); // Show the car details cout << "Car Details:n"; myCar.displayDetails(); return 0; } Example Car Class
  • 6.
    Inheritance in OOP –Inheritance is probably the most powerful feature of object-oriented programming, after classes themselves. – Inheritance is the process of creating new classes, called derived classes, from existing or base classes. – The derived class inherits all the capabilities of the base class but can add embellishments and refinements of its own. – The main class remain unchanged. – Inheritance allows code reusability.
  • 8.
    #include <iostream> using namespacestd; class Counter //base class { protected: //NOTE: not private unsigned int count; //count public: Counter() : count(0) //no-arg constructor { } Counter(int c) : count(c) //1-arg constructor { } unsigned int get_count() const //return count { return count; } Counter operator ++ () //incr count (prefix) { return Counter(++count); } }; class CountDn : public Counter //derived class { public: Counter operator -- () //decr count (prefix) { return Counter(--count); } }; int main() { CountDn c1; //c1 of class CountDn cout << "c1 = " << c1.get_count() << endl; //display c1 ++c1; ++c1; ++c1; cout << "c1 = " << c1.get_count() << endl; //display it --c1; --c1; cout << "c1 = " << c1.get_count() << endl; //display it return 0; } Example
  • 9.
    #include <iostream> using namespacestd; // Base (Super) Class class Shape { private: int height; int width; public: Shape() : height(0), width(0) { } Shape(int h, int w) : height(h), width(w) { } int getHeight() const { return height; } int getWidth() const { return width; } void printData() const { cout << "Height: " << height << endl; cout << "Width: " << width << endl; } }; // Dervied (Sub) Class class Square : public Shape { public: Square() : Shape() { } Square(int s) : Shape(s, s) { } int getArea() const { return getHeight() * getWidth(); } }; // Dervied (Sub) Class class Rectangle : public Shape { public: Rectangle() : Shape() { } Rectangle(int h, int w) : Shape(h, w) { } int getArea() const { return getHeight() * getWidth(); } }; int main() { Square s1(5); Rectangle r1(7, 2); cout << "Square Area: " << s1.getArea() << endl; cout << "Rectangle Area: " << r1.getArea() << endl; return 0; } Example
  • 10.
    The protected AccessSpecifier – A protected member can be accessed by member functions in its own class or in any class derived from its own class. – It can’t be accessed from functions outside these classes, such as main().
  • 11.
    #include <iostream> using namespacestd; class Counter { protected: //NOTE: not private unsigned int count; //count public: Counter() : count(0) //constructor, no args { } Counter(int c) : count(c) //constructor, one arg { } unsigned int get_count() const //return count { return count; } Counter operator ++ () //incr count (prefix) { return Counter(++count); } }; class CountDn : public Counter { public: CountDn() : Counter() //constructor, no args { } CountDn(int c) : Counter(c) //constructor, 1 arg { } CountDn operator -- () //decr count (prefix) { return CountDn(--count); } }; int main() { CountDn c1; //class CountDn CountDn c2(100); cout << "c1 = " << c1.get_count() << endl; //display cout << "c2 = " << c2.get_count() << endl; //display ++c1; ++c1; ++c1; //increment c1 cout << "c1 = " << c1.get_count() << endl; //display it --c2; --c2; //decrement c2 cout << "c2 = " << c2.get_count() << endl; //display it CountDn c3 = --c2; //create c3 from c2 cout << "c3 = " << c3.get_count() << endl; //display c3 return 0; } Derived Class Constructors The CountDn() constructor calls the Counter() constructor in the base class.
  • 12.
    #include <iostream> #include <process.h>//for exit() using namespace std; class Stack { protected: //NOTE: can’t be private enum { MAX = 3 }; //size of stack array int st[MAX]; //stack: array of integers int top; //index to top of stack public: Stack() : top(-1) //constructor { } void push(int var) //put number on stack { st[++top] = var; } int pop() //take number off stack { return st[top--]; } }; class Stack2 : public Stack { public: void push(int var) //put number on stack { if (top >= MAX - 1) //error if stack full { cout << "nError: stack is full"; exit(1); } Stack::push(var); //call push() in Stack class } int pop() //take number off stack { if (top < 0) //error if stack empty { cout << "nError: stack is emptyn"; exit(1); } return Stack::pop(); //call pop() in Stack class } }; int main() { Stack2 s1; s1.push(11); //push some values onto stack s1.push(22); s1.push(33); cout << endl << s1.pop(); //pop some values from stack cout << endl << s1.pop(); cout << endl << s1.pop(); cout << endl << s1.pop(); //oops, popped one too many... return 0; } Overriding Member Functions
  • 13.
    #include <iostream> using namespacestd; enum posneg { pos, neg }; //for sign in DistSign class Distance { protected: //NOTE: can't be private int feet; float inches; public: Distance() : feet(0), inches(0.0) { } Distance(int ft, float in) : feet(ft), inches(in) { } void getdist() { cout << "nEnter feet: "; cin >> feet; cout << "Enter inches: "; cin >> inches; } void showdist() const { cout << feet << "' - " << inches << '"'; } }; class DistSign : public Distance //adds sign to Distance { private: posneg sign; //sign is pos or neg public: DistSign() : Distance() //call base constructor { sign = pos; //set the sign to + } // 2- or 3-arg constructor DistSign(int ft, float in, posneg sg = pos) : Distance(ft, in) //call base constructor { sign = sg; //set the sign } void getdist() //get length from user { Distance::getdist(); //call base getdist() char ch; //get sign from user cout << "Enter sign (+ or -): "; cin >> ch; sign = (ch == '+') ? pos : neg; } void showdist() const //display distance { cout << ((sign == pos) ? "(+)" : "(-)"); //show sign Distance::showdist(); //ft and in } }; int main() { DistSign alpha; //no-arg constructor alpha.getdist(); //get alpha from user DistSign beta(11, 6.25); //2-arg constructor DistSign gamma(100, 5.5, neg); //3-arg constructor //display all distances cout << "nalpha = "; alpha.showdist(); cout << "nbeta = "; beta.showdist(); cout << "ngamma = "; gamma.showdist(); return 0; } Derived Class Constructors More Complex Example
  • 15.
  • 16.
    #include <iostream> using namespacestd; const int LEN = 80; //maximum length of names class employee //employee class { private: char name[LEN]; //employee name unsigned long number; //employee number public: void getdata() { cout << "n Enter last name: "; cin >> name; cout << " Enter number: "; cin >> number; } void putdata() const { cout << "n Name: " << name; cout << "n Number: " << number; } }; class manager : public employee //management class { private: char title[LEN]; //"vice-president" etc. double dues; //golf club dues public: void getdata() { employee::getdata(); cout << " Enter title: "; cin >> title; cout << " Enter golf club dues: "; cin >> dues; } void putdata() const { employee::putdata(); cout << "n Title: " << title; cout << "n Golf club dues: " << dues; } }; class scientist : public employee //scientist class { private: int pubs; //number of publications public: void getdata() { employee::getdata(); cout << " Enter number of pubs: "; cin >> pubs; } void putdata() const { employee::putdata(); cout << "n Number of publications: " << pubs; } }; class laborer : public employee //laborer class { }; int main() { manager m1; scientist s1; laborer l1; //get data for several employees cout << "nEnter data for manager 1"; m1.getdata(); cout << "nEnter data for scientist 1"; s1.getdata(); cout << "nEnter data for laborer 1"; l1.getdata(); //display data for several employees cout << "nData on manager 1"; m1.putdata(); cout << "nData on scientist 1"; s1.putdata(); cout << "nData on laborer 1"; l1.putdata(); return 0; } Example Class Hierarchies
  • 18.
    #include <iostream> using namespacestd; class A //base class { private: int privdataA; protected: int protdataA; public: int pubdataA; }; class B : public A //publicly-derived class { public: void funct() { int a; a = privdataA; //error: not accessible a = protdataA; //OK a = pubdataA; //OK } }; class C : private A //privately-derived class { public: void funct() { int a; a = privdataA; //error: not accessible a = protdataA; //OK a = pubdataA; //OK } }; int main() { int a; B objB; a = objB.privdataA; //error: not accessible a = objB.protdataA; //error: not accessible a = objB.pubdataA; //OK (A public to B) C objC; a = objC.privdataA; //error: not accessible a = objC.protdataA; //error: not accessible a = objC.pubdataA; //error: not accessible (A private to C) return 0; } publicly- and privately- derived classes
  • 21.
    Multiple Inheritance UML ClassDiagram class A // base class A { }; class B // base class B { }; class C : public A, public B // C is derived from A and B { };
  • 22.
    #include <iostream> using namespacestd; const int LEN = 80; //maximum length of names class student //educational background { private: char school[LEN]; //name of school or university char degree[LEN]; //highest degree earned public: void getedu() { cout << " Enter name of school or university: "; cin >> school; cout << " Enter highest degree earned (Highschool, Bachelor’s, Master’s, PhD): "; cin >> degree; } void putedu() const { cout << "n School or university: " << school; cout << "n Highest degree earned: " << degree; } }; class employee { private: char name[LEN]; //employee name unsigned long number; //employee number public: void getdata() { cout << "n Enter last name: "; cin >> name; cout << " Enter number: "; cin >> number; } void putdata() const { cout << "n Name: " << name; cout << "n Number: " << number; } }; class manager : private employee, private student //management { private: char title[LEN]; //"vice-president" etc. double dues; //golf club dues public: void getdata() { employee::getdata(); cout << " Enter title: "; cin >> title; cout << " Enter golf club dues: "; cin >> dues; student::getedu(); } void putdata() const { employee::putdata(); cout << "n Title: " << title; cout << "n Golf club dues: " << dues; student::putedu(); } }; class scientist : private employee, private student //scientist { private: int pubs; //number of publications public: void getdata() { employee::getdata(); cout << " Enter number of pubs: "; cin >> pubs; student::getedu(); } void putdata() const { employee::putdata(); cout << "n Number of publications: " << pubs; student::putedu(); } }; class laborer : public employee //laborer { }; int main() { manager m1; scientist s1; laborer l1; //get data for several employees cout << "nEnter data for manager 1"; m1.getdata(); cout << "nEnter data for scientist 1"; s1.getdata(); cout << "nEnter data for laborer 1"; l1.getdata(); //display data for several employees cout << "nData on manager 1"; m1.putdata(); cout << "nData on scientist 1"; s1.putdata(); cout << "nData on laborer 1"; l1.putdata(); return 0; } Example
  • 23.
    private Derivation – Themanager and scientist classes in EMPMULT are privately derived from the employee and student classes. – There is no need to use public derivation because objects of manager and scientist never call routines in the employee and student base classes. – However, the laborer class must be publicly derived from employer, since it has no member functions of its own and relies on those in employee.
  • 24.
    #include <iostream> #include <string> usingnamespace std; class Person { private: string name; int age; public: Person() : name(""), age(0) { } Person(string n, int a) : name(n), age(a) { } void getPerson() //get person from user { cout << "tEnter name: "; cin >> name; cout << "tEnter age: "; cin >> age; } void showPerson() const //display type { cout << "tName: " << name << endl; cout << "tAge: " << age << endl; } }; class Employee { private: string ID; double salary; public: Employee() : ID(""), salary(0.0) { } Employee(string id, double s) : ID(id), salary(s) { } void getEmployee() //get Employee from user { cout << "tEnter ID: "; cin >> ID; cout << "tEnter salary: "; cin >> salary; } void showEmployee() const //display Employee { cout << "tID: " << ID << endl; cout << "tSalary: " << salary << endl; } }; class Teacher : public Person, public Employee { private: string rank; public: Teacher() : Person(), Employee(), rank("") { } Teacher(string name, int age, string ID, double salary, string r) : Person(name, age), Employee(ID, salary), rank(r) { } void getTeacher() { Person::getPerson(); Employee::getEmployee(); cout << "tEnter rank: "; cin >> rank; } void showTeacher() const { Person::showPerson(); Employee::showEmployee(); cout << "trank: " << rank << endl; } }; int main() { Teacher t1; cout << "Enter Teacher 1 data:nn"; t1.getTeacher(); Teacher t2("Ahmed", 38, "1234", 2500, "Excellent"); //display Teacher data cout << "nnTeacher 1:n"; t1.showTeacher(); cout << "nnTeacher 2:n"; t2.showTeacher(); return 0; } Constructors in Multiple Inheritance
  • 25.
    #include <iostream> using namespacestd; class A { public: void show() { cout << "Class An"; } }; class B { public: void show() { cout << "Class Bn"; } }; class C : public A, public B {}; int main() { C objC; //object of class C // objC.show(); //ambiguous--will not compile objC.A::show(); //OK objC.B::show(); //OK return 0; } Ambiguity in Multiple Inheritance 1) Two base classes have functions with the same name, while a class derived from both base classes has no function with this name. How do objects of the derived class access the correct base class function?
  • 26.
    #include <iostream> using namespacestd; class A { public: void func(); }; class B : public A { }; class C : public A { }; class D : public B, public C { }; int main() { D objD; objD.func(); //ambiguous: won’t compile return 0; } Ambiguity in Multiple Inheritance 2) Another kind of ambiguity arises if you derive a class from two classes that are each derived from the same class. This creates a diamond-shaped inheritance tree.
  • 27.
    #include <iostream> #include <string> usingnamespace std; class student //educational background { private: string school; //name of school or university string degree; //highest degree earned public: void getedu() { cout << " Enter name of school or university: "; cin >> school; cout << " Enter highest degree earned (Highschool, Bachelor’s, Master’s, PhD): "; cin >> degree; } void putedu() const { cout << "n School or university: " << school; cout << "n Highest degree earned: " << degree; } }; class employee { private: string name; //employee name unsigned long number; //employee number public: void getdata() { cout << "n Enter last name: "; cin >> name; cout << " Enter number: "; cin >> number; } void putdata() const { cout << "n Name: " << name; cout << "n Number: " << number; } }; class manager //management { private: string title; //"vice-president" etc. double dues; //golf club dues employee emp; //** object of class employee student stu; //** object of class student public: void getdata() { emp.getdata(); cout << " Enter title: "; cin >> title; cout << " Enter golf club dues: "; cin >> dues; stu.getedu(); } void putdata() const { emp.putdata(); cout << "n Title: " << title; cout << "n Golf club dues: " << dues; stu.putedu(); } }; class scientist //scientist { private: int pubs; //number of publications employee emp; //** object of class employee student stu; //** object of class student public: void getdata() { emp.getdata(); cout << " Enter number of pubs: "; cin >> pubs; stu.getedu(); } void putdata() const { emp.putdata(); cout << "n Number of publications: " << pubs; stu.putedu(); } }; class laborer //laborer { private: employee emp; //object of class employee public: void getdata() { emp.getdata(); } void putdata() const { emp.putdata(); } }; int main() { manager m1; scientist s1; laborer l1; //get data for several employees cout << "nEnter data for manager 1"; m1.getdata(); cout << "nEnter data for scientist 1"; s1.getdata(); cout << "nEnter data for laborer 1"; l1.getdata(); //display data for several employees cout << "nData on manager 1"; m1.putdata(); cout << "nData on scientist 1"; s1.putdata(); cout << "nData on laborer 1"; l1.putdata(); return 0; } Aggregation instead of inheritance 2) Another kind of ambiguity arises if you derive a class from two classes that are each derived from the same class. This creates a diamond-shaped inheritance tree.
  • 28.
    End of lecture3 ThankYou!