1
Another Way to Define A Class - Inheritance
2
Inheritance Concept
Rectangle Triangle
Polygon
class Polygon
{
private:
int width, length;
public:
void set(int w, int l);
}
class Rectangle{
private:
int width, length;
public:
void set(int w, int l);
int area();
}
class Triangle{
private:
int width, length;
public:
void set(int w, int l);
int area();
}
3
Rectangle Triangle
Polygonclass Polygon
{
protected:
int width, length;
public:
void set(int w, int l);
}
class Rectangle : public Polygon
{
public: int area();
}
class Rectangle{
protected:
int width, length;
public:
void set(int w, int l);
int area();
}
Inheritance Concept
4
Rectangle Triangle
Polygonclass Polygon
{
protected:
int width, length;
public:
void set(int w, int l);
}
class Triangle : public Polygon
{
public: int area();
}
class Triangle{
protected:
int width, length;
public:
void set(int w, int l);
int area();
}
Inheritance Concept
5
Inheritance Concept
Point
Circle 3D-Point
class Point
{
protected:
int x, y;
public:
void set(int a, int b);
}
class Circle : public Point
{
private:
double r;
}
class 3D-Point: public Point
{
private:
int z;
}
xy
xyr
xyz
6
• Augmenting the original class
• Specializing the original class
Inheritance Concept
RealNumber
ComplexNumber
ImaginaryNumber
Rectangle Triangle
Polygon Point
Circle
realimag
real imag
3D-Point
7
Why Inheritance ?
Inheritance is a mechanism for
• building class types from existing class types
• defining new class types to be a – specialization – augmentation
of existing types
8
Define a Class Hierarchy
• Syntax:
class DerivedClassName : access-level BaseClassName
where
– access-level specifies the type of derivation
• private by default, or
• public
• Any class can serve as a base class– Thus a derived class can also be a base class
9
Class Derivation
Point
3D-Point
class Point{
protected:
int x, y;
public:
void set(int a, int b);
}
class 3D-Point : public Point{
private: double z;
… …
}
class Sphere : public 3D-Point{
private: double r;
… …
}
Sphere
Point is the base class of 3D-Point, while 3D-Point is the base class of Sphere
10
What to inherit?
• In principle, every member of a base class is inherited by a derived class– just with different access permission
11
Access Control Over the Members
• Two levels of access control over class members– class definition
– inheritance type
base c lass / supe rc lass /pa ren t c lass
deriv ed c lass / subc lass /ch ild c lass
deriv
e fro
m
mem
bers
goe
s to
class Point{
protected: int x, y;
public: void set(int a, int b);
}
class Circle : public Point{
… …
}
12
• The type of inheritance defines the minimum access level for the members of derived class that are inherited from the base class
• With public inheritance, the derived class follow the same access permission as in the base class
• With protected inheritance, only the public members inherited from the base class can be accessed in the derived class as protected members
• With private inheritance, none of the members of base class is accessible by the derived class
Access Rights of Derived Classes
private protected public
private private private private
protected private private protected
public private protected public
Type of Inheritance
Access
Control
for Mem
bers
13
Class Derivation
mother
daughter son
class mother{
protected:
int x, y;
public:
void set(int a, int b);
private:
int z;
}
class daughter : public mother{
private:
double a;
public:
void foo ( );
}
void daughter :: foo ( ){
x = y = 20;
set(5, 10);
cout<<“value of a ”<<a<<endl;
z = 100; // error, a private member
}
daughter can access 3 of the 4 inherited members
14
Class Derivation
mother
daughter son
class mother{
protected:
int x, y;
public:
void set(int a, int b);
private:
int z;
}
class son : protected mother{
private:
double b;
public:
void foo ( );
}
void son :: foo ( ){
x = y = 20; // error, not a public member
set(5, 10);
cout<<“value of b ”<<b<<endl;
z = 100; // error, not a public member
}
son can access only 1 of the 4 inherited member
15
What to inherit?
• In principle, every member of a base class is inherited by a derived class– just with different access permission
• However, there are exceptions for– constructor and destructor – operator=() member – friends
Since all these functions are class-specific
16
Constructor Rules for Derived Classes
The default constructor and the destructor of the base class are always called when a new object of a derived class is created or destroyed.
class A {
public:
A ( )
{cout<< “A:default”<<endl;}
A (int a)
{cout<<“A:parameter”<<endl;}
}
class B : public A
{
public:
B (int a)
{cout<<“B”<<endl;}
}
B test(1);A:defaultB
output:
17
Constructor Rules for Derived Classes You can also specify an constructor of the base class other than the default constructor
class A {
public:
A ( )
{cout<< “A:default”<<endl;}
A (int a)
{cout<<“A:parameter”<<endl;}
}
class C : public A
{
public:
C (int a) : A(a)
{cout<<“C”<<endl;}
}
C test(1);A:parameterC
output:
DerivedClassCon ( derivedClass args ) : BaseClassCon ( baseClass args )
{ DerivedClass constructor body }
18
Define its Own Members
Point
Circle
class Point{
protected:
int x, y;
public:
void set(int a, int b);
}
class Circle : public Point{
private:
double r;
public:
void set_r(double c);
}
xy
xyr protected:
int x, y;
private:
double r;
public:
void set(int a, int b);
void set_r(double c);
The derived class can also define its own members, in addition to the members inherited from the base class
19
Even more …
• A derived class can override methods defined in its parent
class. With overriding, – the method in the subclass has the identical signature to the
method in the base class.
– a subclass implements its own version of a base class method.
class A {
protected:
int x, y;
public:
void print ()
{cout<<“From A”<<endl;}
}
class B : public A
{
public:
void print ()
{cout<<“From B”<<endl;}
}
20
class Point
{
protected:
int x, y;
public:
void set(int a, int b)
{x=a; y=b;}
void foo ();
void print();
}
class Circle : public Point{
private: double r;
public:
void set (int a, int b, double c) {
Point :: set(a, b); //same name function call
r = c;
}
void print(); }
Access a Method
Circle C;
C.set(10,10,100); // from class Circle
C.foo (); // from base class Point
C.print(); // from class Circle
Point A;
A.set(30,50); // from base class Point
A.print(); // from base class Point
21
Putting Them Together
• Time is the base class• ExtTime is the derived class with
public inheritance• The derived class can
– inherit all members from the base class, except the constructor
– access all public and protected members of the base class
– define its private data member– provide its own constructor– define its public member functions– override functions inherited from
the base class
ExtTime
Time
22
class Time Specification
class Time{
public :
void Set ( int h, int m, int s ) ;void Increment ( ) ;void Write ( ) const ;Time ( int initH, int initM, int initS ) ; // constructor Time ( ) ; // default constructor
protected :
int hrs ; int mins ; int secs ;
} ;
// SPECIFICATION FILE ( time.h)
23
Class Interface Diagram
Protected data:
hrs
mins
secs
Set
Increment
Write
Time
Time
Time class
24
Derived Class ExtTime // SPECIFICATION FILE ( exttime.h)
#include “time.h”
enum ZoneType {EST, CST, MST, PST, EDT, CDT, MDT, PDT } ;
class ExtTime : public Time // Time is the base class and use public inheritance
{ public :
void Set ( int h, int m, int s, ZoneType timeZone ) ;void Write ( ) const; //overridden
ExtTime (int initH, int initM, int initS, ZoneType initZone ) ; ExtTime (); // default constructor
private :ZoneType zone ; // added data member
} ;
25
Class Interface Diagram
Protected data:
hrs
mins
secs
ExtTime class
Set
Increment
Write
Time
Time
Set
Increment
Write
ExtTime
ExtTime
Private data:zone
26
Implementation of ExtTime
Default Constructor
ExtTime :: ExtTime ( ){
zone = EST ;}
The default constructor of base class, Time(), is automatically called, when an ExtTime object is created.
ExtTime et1;
hrs = 0mins = 0secs = 0zone = EST
et1
27
Implementation of ExtTime
Another Constructor
ExtTime :: ExtTime (int initH, int initM, int initS, ZoneType initZone) : Time (initH, initM, initS) // constructor initializer
{ zone = initZone ;}
ExtTime *et2 =
new ExtTime(8,30,0,EST);hrs = 8mins = 30secs = 0zone = EST
et2
5000
???
6000
5000
28
Implementation of ExtTime
void ExtTime :: Set (int h, int m, int s, ZoneType timeZone)
{
Time :: Set (hours, minutes, seconds); // same name function call
zone = timeZone ;
}
void ExtTime :: Write ( ) const // function overriding
{
string zoneString[8] =
{“EST”, “CST”, MST”, “PST”, “EDT”, “CDT”, “MDT”, “PDT”} ;
Time :: Write ( ) ;
cout <<‘ ‘<<zoneString[zone]<<endl;
}
29
Working with ExtTime
#include “exttime.h”… …
int main() {
ExtTime thisTime ( 8, 35, 0, PST ) ; ExtTime thatTime ; // default constructor called
thatTime.Write( ) ; // outputs 00:00:00 EST
thatTime.Set (16, 49, 23, CDT) ; thatTime.Write( ) ; // outputs 16:49:23 CDT
thisTime.Increment ( ) ;thisTime.Increment ( ) ;thisTime.Write ( ) ; // outputs 08:35:02 PST
}
30
Inheritance Summary
• Inheritance is a mechanism for defining new class types to be a specialization or an augmentation of existing types.
• In principle, every member of a base class is inherited by a derived class with different access permissions, except for the constructors
31
More C++ Concepts
• Operator overloading
• Friend Function
• This Operator
• Inline Function
32
Review• There are different types of member functions in the definition
of a class– Accessor
• int Str :: get_length();
– implementor/worker• void Rectangle :: set(int, int);
– helper• void Date :: errmsg(const char* msg);
– constructor• Account :: Account();• Account :: Account(const Account& a);• Account :: Account(const char *person);
– destructor• Account :: ~Account();
33
Operator overloading
• Programmer can use some operator symbols to define special member functions of a class
• Provides convenient notations for object behaviors
34
int i, j, k; // integers
float m, n, p; // floats
k = i + j;
// integer addition and assignment
p = m + n;
// floating addition and assignment
Why Operator Overloading
The compiler overloads the + operator for built-in integer and float types by default, producing integer addition with i+j, and floating addition with m+n.
We can make object operation look like individual int variable operation, using operator functions
Date a,b,c;c = a + b;
35
Operator Overloading Syntax
• Syntax is:
operator@(argument-list)
--- operator is a function
--- @ is one of C++ operator symbols (+, -, =, etc..)
Examples:
operator+
operator-
operator*
operator/
36
class CStr {
char *pData;int nLength;
public:// …void cat(char *s);// …
friend CStr operator+(CStr str1, CStr str2);friend CStr operator+(CStr str, char *s);friend CStr operator+(char *s, CStr str);
//accessorschar* get_Data();
int get_Len();
};
Example of Operator Overloading
void CStr::cat(char *s){ int n; char *pTemp; n=strlen(s); if (n==0) return;
pTemp=new char[n+nLength+1]; if (pData) strcpy(pTemp,pData);
strcat(pTemp,s); pData=pTemp; nLength+=n;}
37
The Addition (+) Operator
CStr operator+(CStr str1, CStr str2){ CStr new_string(str1);
//call the copy constructor to initialize an entirely new CStr object with the first operand
new_string.cat(str2.get_Data());//concatenate the second operand onto
the end of new_string return new_string;
//call copy constructor to create a copy of the return value new_string
}
new_string
str1strlen(str1)
strcat(str1,str2)strlen(str1)+strlen(str2)
38
How does it work?CStr first(“John”);CStr last(“Johnson”);CStr name(first+last);
CStr operator+(CStr str1,CStr str2) {CStr new_string(str1);new_string.cat(str2.get());return new_string;
}
“John Johnson”
Temporary CStr objectCopy constructor
name
39
Implementing Operator Overloading
• Two ways:– Implemented as member functions – Implemented as non-member or Friend functions
• the operator function may need to be declared as a friend if it requires access to protected or private data
• Expression obj1@obj2 translates into a function call
– obj1.operator@(obj2), if this function is defined within class obj1
– operator@(obj1,obj2), if this function is defined outside the class obj1
40
1. Defined as a member function
Implementing Operator Overloading
class Complex { ... public: ... Complex operator +(const Complex &op) { double real = _real + op._real, imag = _imag + op._imag; return(Complex(real, imag)); } ... };
c = a+b;
c = a.operator+ (b);
41
2. Defined as a non-member function
Implementing Operator Overloading
class Complex { ... public: ... double real() { return _real; } //need access functions double imag() { return _imag; } ... };
Complex operator +(Complex &op1, Complex &op2) { double real = op1.real() + op2.real(), imag = op1.imag() + op2.imag(); return(Complex(real, imag));}
c = a+b;
c = operator+ (a, b);
42
3. Defined as a friend function
Implementing Operator Overloading
class Complex { ... public: ... friend Complex operator +( const Complex &, const Complex & ); ... };
Complex operator +(Complex &op1, Complex &op2) { double real = op1._real + op2._real, imag = op1._imag + op2._imag; return(Complex(real, imag));}
c = a+b;
c = operator+ (a, b);
43
What is ‘Friend’?
• Friend declarations introduce extra coupling between classes– Once an object is declared as a friend, it has access
to all non-public members as if they were public
• Access is unidirectional– If B is designated as friend of A, B can access A’s
non-public members; A cannot access B’s
• A friend function of a class is defined outside of that class's scope
44
More about ‘Friend’
• The major use of friends is – to provide more efficient access to data members than
the function call– to accommodate operator functions with easy access to
private data members
• Friends can have access to everything, which defeats data hiding, so use them carefully
• Friends have permission to change the internal state from outside the class. Always recommend use member functions instead of friends to change state
45
Assignment Operator
• Assignment between objects of the same type is always supported
– the compiler supplies a hidden assignment function if you don’t write your own one
– same problem as with the copy constructor - the member by member copying
– Syntax:
class& class::operator=(const class &arg) {
//…}
46
Example: Assignment for CStr class
CStr& operator=(const CStr &source){
//... Do the copying
return *this;
}
Assignment operator for CStr:
CStr& operator=(const CStr & source)
Return type - a reference to (address of) a CStr object
Argument type - a reference to a CStr object (since it is const, the function cannot modify it)
Assignment function is called as a member function of the left operand =>Return the object itself
str1=str2;
str1.operator=(str2)
47
Overloading stream-insertion and stream-extraction operators
• In fact, cout<< or cin>> are operator overloading built in C++ standard lib of iostream.h, using operator "<<" and ">>"
• cout and cin are the objects of ostream and istream classes, respectively
• We can add a friend function which overloads the operator <<
friend ostream& operator<< (ostream &ous, const Date &d);
ostream& operator<<(ostream &os, const Date &d){ os<<d.month<<“/”<<d.day<<“/”<<d.year; return os;}…cout<< d1; //overloaded operator
ostream& operator<<(ostream &os, const Date &d){ os<<d.month<<“/”<<d.day<<“/”<<d.year; return os;}…cout<< d1; //overloaded operator
cout ---- object of ostreamcout ---- object of ostream
48
Overloading stream-insertion and stream-extraction operators
• We can also add a friend function which overloads the operator >>
istream& operator>> (istream &in, Date &d) { char mmddyy[9];
in >> mmddyy;
// check if valid data entered if (d.set(mmddyy)) return in;
cout<< "Invalid date format: "<<d<<endl; exit(-1); }
friend istream& operator>> (istream &in, Date &d);
cin ---- object of istream
cin >> d1;
49
The “this” pointer • Within a member function, the this keyword is a pointer to the current
object, i.e. the object through which the function was called
• C++ passes a hidden this pointer whenever a member function is called
• Within a member function definition, there is an implicit use of this pointer for references to data members
pData
nLength
this Data member reference Equivalent to
pData this->pData
nLength this->nLength
CStr object(*this)
50
Inline functions• An inline function is one in which the function
code replaces the function call directly.• Inline class member functions
– if they are defined as part of the class definition, implicit
– if they are defined outside of the class definition, explicit, I.e.using the keyword, inline.
• Inline functions should be short (preferable one-liners). – Why? Because the use of inline function results in
duplication of the code of the function for each invocation of the inline function
51
class CStr{ char *pData; int nLength; … public:
… char *get_Data(void) {return pData; }//implicit inline function int getlength(void); …};
inline void CStr::getlength(void) //explicit inline function{ return nLength;} … int main(void){ char *s; int n; CStr a(“Joe”); s = a.get_Data(); n = b.getlength();}
Example of Inline functions
Inline functions within class declarations
Inline functions outside of class declarations
In both cases, the compiler will insert the code of the functions get_Data() and getlength() instead of generating calls to these functions
52
Inline functions
• An inline function can never be located in a run-time library since the actual code is inserted by the compiler and must therefore be known at compile-time.
• It is only useful to implement an inline function when the time which is spent during a function call is long compared to the code in the function.
53
Overloading Summary
• Operator overloading provides convenient notations for object behaviors
• There are three ways to implement operator overloading– member functions– normal non-member functions– friend functions
54
Polymorphism
55
Object-Oriented Concept
• Encapsulation– ADT, Object
• Inheritance– Derived object
• Polymorphism– Each object knows what it is
56
Polymorphism – An Introduction
• noun, the quality or state of being able to assume different forms - Webster
• An essential feature of an OO Language
• It builds upon Inheritance
57
Before we proceed….
• Inheritance – Basic Concepts– Class Hierarchy
• Code Reuse, Easy to maintain
– Type of inheritance : public, private– Function overriding
58
Class Interface Diagram
Protected data:
hrs
mins
secs
ExtTime class
Set
Increment
Write
Time
Time
Set
Increment
Write
ExtTime
ExtTime
Private data:zone
Time class
59
Why Polymorphism?--Review: Time and ExtTime Example by Inheritance
void Print (Time someTime ) //pass an object by value{
cout << “Time is “ ;someTime.Write ( ) ;cout << endl ;
}
CLIENT CODE
Time startTime ( 8, 30, 0 ) ;ExtTime endTime (10, 45, 0, CST) ;
Print ( startTime ) ;Print ( endTime ) ;
OUTPUT
Time is 08:30:00 Time is 10:45:00
// Time :: write()
60
Static Binding
• When the type of a formal parameter is a parent class, the argument used can be:
the same type as the formal parameter,
or,
any derived class type.
• Static binding is the compile-time determination of which function to call for a particular object based on the type of the formal parameter
• When pass-by-value is used, static binding occurs
61
Polymorphism – An Introduction
• noun, the quality or state of being able to assume different forms - Webster
• An essential feature of an OO Language
• It builds upon Inheritance
• Allows run-time interpretation of object type for a given class hierarchy– Also Known as “Late Binding”
• Implemented in C++ using virtual functions
62
Dynamic Binding
• Is the run-time determination of which function to call for a particular object of a derived class based on the type of the argument
• Declaring a member function to be virtual instructs the compiler to generate code that guarantees dynamic binding
• Dynamic binding requires pass-by-reference
63
Virtual Member Function
// SPECIFICATION FILE ( time.h )
class Time{public :
. . .
virtual void Write ( ) ; // for dynamic bindingvirtual ~Time(); // destructor
private :
int hrs ; int mins ; int secs ;
} ;
64
This is the way we like to see…
void Print (Time * someTime ) {
cout << “Time is “ ;someTime->Write ( ) ;cout << endl ;
}
CLIENT CODE
Time startTime( 8, 30, 0 ) ; ExtTime endTime(10, 45, 0, CST) ;
Time *timeptr;timeptr = &startTime;Print ( timeptr ) ;
timeptr = &endTime;Print ( timeptr ) ;
OUTPUT
Time is 08:30:00 Time is 10:45:00 CST
Time::write()
ExtTime::write()
65
Virtual Functions • Virtual Functions overcome the problem of run time
object determination• Keyword virtual instructs the compiler to use late
binding and delay the object interpretation• How ?
– Define a virtual function in the base class. The word virtual appears only in the base class
– If a base class declares a virtual function, it must implement that function, even if the body is empty
– Virtual function in base class stays virtual in all the derived classes
– It can be overridden in the derived classes
– But, a derived class is not required to re-implement a virtual function. If it does not, the base class version is used
66
Polymorphism Summary:
• When you use virtual functions, compiler store additional information about the types of object available and created
• Polymorphism is supported at this additional overhead
• Important :– virtual functions work only with pointers/references
– Not with objects even if the function is virtual
– If a class declares any virtual methods, the destructor of the class should be declared as virtual as well.
67
Abstract Classes & Pure Virtual Functions
• Some classes exist logically but not physically.
• Example : Shape– Shape s; // Legal but silly..!! : “Shapeless shape”
– Shape makes sense only as a base of some classes derived from it. Serves as a “category”
– Hence instantiation of such a class must be prevented
class Shape //Abstract { public : //Pure virtual Function virtual void draw() = 0;}
A class with one or more pure virtual functions is an Abstract Class
Objects of abstract class can’t be created
Shape s; // error : variable of an abstract class
68
Example
Shape
virtual void draw()
Circle
public void draw()
Triangle
public void draw()
69
• A pure virtual function not defined in the derived class remains a pure virtual function.
• Hence derived class also becomes abstract
class Circle : public Shape { //No draw() - Abstractpublic :void print(){ cout << “I am a circle” << endl;}
class Rectangle : public Shape {public :void draw(){ // Override Shape::draw() cout << “Drawing Rectangle” << endl;}
Rectangle r; // Valid
Circle c; // error : variable of an abstract class
70
Pure virtual functions : Summary
• Pure virtual functions are useful because they make explicit the abstractness of a class
• Tell both the user and the compiler how it was intended to be used
• Note : It is a good idea to keep the common code as close as possible to the root of you hierarchy
71
Summary ..continued• It is still possible to provide definition of a pure virtual function in
the base class• The class still remains abstract and functions must be redefined in
the derived classes, but a common piece of code can be kept there to facilitate reuse
• In this case, they can not be declared inline
class Shape { //Abstract public : virtual void draw() = 0;
};
// OK, not defined inline void Shape::draw(){ cout << “Shape" << endl;}
class Rectangle : public Shape
{ public : void draw(){ Shape::draw(); //Reuse cout <<“Rectangle”<< endl;}
72
Polymorphism Summary
• Polymorphism is built upon class inheritance
• It allows different versions of a function to be called in the same manner, with some overhead
• Polymorphism is implemented with virtual functions, and requires pass-by-reference
Top Related