0% found this document useful (0 votes)
14 views32 pages

09 Inheritance

Uploaded by

e24115025
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
14 views32 pages

09 Inheritance

Uploaded by

e24115025
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 32

Inheritance

Yean-Ru Chen
EE, NCKU

Slides contents ack to Prof. Meng-Hsun Tsai @ NCKU CSIE


Introduction
• Inheritance is a form of software reuse in which you create a class that absorbs an
existing class’s data and behaviors and enhances them with new capabilities.

• This existing class is called the base class, and the new class is referred to as the
derived class.

• A derived class contains behaviors inherited from its base class and can contain
additional behaviors.

• A derived class can also customize behaviors inherited from the base class.

inheritance derived class


Student TA
base class
eating( ) client
coding( ) coding( )
grading( )
2
Direct vs. Indirect Base Class and
Single vs. Multiple Inheritance

• A direct base class is the base class from which a derived class
explicitly inherits.

• An indirect base class is inherited from two or more levels up in the


class hierarchy.

• In the case of single inheritance, a class is derived from one base class.

• C++ also supports multiple inheritance, in which a derived class


inherits from multiple (possibly unrelated) base classes.

3
Direct vs. Indirect Base Class and
Single vs. Multiple Inheritance (cont.)
indirect base class direct base class derived class

Human Student TA
single multiple
inheritance inheritance eating( )
eating( ) eating( )
coding( )
coding( )
grading( )
teaching( )

Grader

grading( )

4
public, private and protected Inheritance

• C++ offers public, private and protected inheritance.

• In this lecture, we concentrate on public inheritance and briefly


explain the other two.

• The third form, protected inheritance, is rarely used.

• Every object of a derived class is also an object of that derived class’s


base class.

• However, base-class objects are not objects of their derived classes.

5
is-a vs. has-a Relationship

• We distinguish between the is-a relationship and the has-a relationship.

• The is-a relationship represents inheritance.

• In an is-a relationship, an object of a derived class also can be treated


as an object of its base class.

• By contrast, the has-a relationship represents composition.

6
Base Classes and Derived Classes

• Often, an object of one class is an object of another class, as well.


• For example, in geometry, a rectangle (長方形) is a
quadrilateral (四邊形) (as are squares 正方形,
parallelograms 平行四邊形 and trapezoids 梯形).
• Thus, in C++, class Rectangle can be said to inherit
from class Quadrilateral.
• A rectangle is a specific type of quadrilateral, but it’s
incorrect to claim that a quadrilateral is a rectangle—the
quadrilateral could be a parallelogram or some other
shape.

7
Base Classes and Derived Classes (cont.)

• A base class exists in a hierarchical relationship with its derived


classes.

• A class becomes either a base class—supplying members to other


classes, a derived class—inheriting its members from other classes, or
both.

• In the UML diagram, each arrow in the hierarchy represents an is-a


relationship. For example, A TA is a student. A student is a human.

Human

Student Grader

TA 8
Tetrominos in Tetris Game
https://www.youtube.com/watch?v=8ArEKGDfg2E

I : four blocks in a straight line

J : a row of three blocks with L : a reflection of J but


one added below the right cannot be rotated into J
side. in two dimensions

S : two stacked horizontal Z : a reflection of S but


dominoes with the top one cannot be rotated into S in
offset to the right two dimensions

O : four blocks in a 2×2 square.

T : a row of three blocks with one added


below the center

Source: http://en.wikipedia.org/wiki/Tetris
http://en.wikipedia.org/wiki/Tetromino 9
IBlock.h

1 #ifndef I_BLOCK_H 20 I_Block& left() {x=(x>0)?(x-1):10;


2 #define I_BLOCK_H return *this;}
3 #include <iostream> 21 I_Block& right() {x=(x>10)?0:x+1;
4 using namespace std; return *this;}
5 char I_arr [2][4][4] = {{{'0','0','1','0'}, 22 void paint() {
6 {'0','0','1','0'}, 23 for(int i=0;i<4;++i)
7 {'0','0','1','0'}, 24 {
8 {'0','0','1','0'}}, 25 for(int j=0;j<x;++j) cout << ' ';
9 {{'0','0','0','0'}, 26 for(int j=0;j<4;++j)
10 {'0','0','0','0'}, 27 cout << I_arr[rotate_index][i][j];
11 {'1','1','1','1'}, 28 cout << endl;
12 {'0','0','0','0'}} }; 29 }
13 class I_Block{ 30 cout << endl;
14 public: 31 }
15 I_Block():x(0),y(0),rotate_index(0) {} 32 public:
16 I_Block& rotate(){ 33 int x, y;
17 rotate_index=(rotate_index>0)? 34 int rotate_index;
0:rotate_index+1; 35 };
18 return *this; 36 #endif
19 } 10
tetris.cpp
0010
0010
1 #include <iostream> 0010
2 #include "IBlock.h" 0010
3 using namespace std;
4 int main()
0000
5 { 0000
6 I_Block i; 1111
7 i.paint(); 0000
8 i.rotate().paint(); 0000
9 i.right().paint();
10 i.right().rotate().paint(); 0000
11 return 0; 1111
12 } 0000
0010
0010
0010
0010
11
Adding SBlock.h Without Inheritance

1 #ifndef S_BLOCK_H 20 S_Block& left() {x=(x>0)?(x-1):10;


2 #define S_BLOCK_H return *this;}
3 #include <iostream> 21 S_Block& right() {x=(x>10)?0:x+1;
4 using namespace std; return *this;}
5 char S_arr [2][4][4] = {{{'0','0','0','0'}, 22 void paint() {
6 {'0','0','0','0'}, 23 for(int i=0;i<4;++i)
7 {'0','0','1','1'}, 24 {
8 {'0','1','1','0'}}, 25 for(int j=0;j<x;++j) cout << ' ';
9 {{'0','0','0','0'}, 26 for(int j=0;j<4;++j)
10 {'0','1','0','0'}, 27 cout << S_arr[rotate_index][i][j];
11 {'0','1','1','0'}, 28 cout << endl;
12 {'0','0','1','0'}} }; 29 }
13 class S_Block{ 30 cout << endl;
14 public: 31 }
15 S_Block():x(0),y(0),rotate_index(0) {}; 32 private:
16 S_Block& rotate(){ 33 int x, y;
17 rotate_index=(rotate_index>0)? 34 int rotate_index;
0:rotate_index+1; 35 };
18 return *this; 36 #endif
19 }
Most codes are the same as IBlock.h! 12
Adding SBlock_inh.h With Inheritance

1 #ifndef S_BLOCK_INH_H 14 class S_Block: public I_Block{


2 #define S_BLOCK_INH_H 15 public:
3 #include <iostream> 16 void paint() {
4 #include "IBlock.h" 17 for(int i=0;i<4;++i)
5 using namespace std; 18 {
6 char S_arr [2][4][4] = {{{'0','0','0','0'}, 19 for(int j=0;j<x;++j) cout << ' ';
7 {'0','0','0','0'}, 20 for(int j=0;j<4;++j)
8 {'0','0','1','1'}, 21 cout << S_arr[rotate_index][i][j];
9 {'0','1','1','0'}}, 22 cout << endl;
10 {{'0','0','0','0'}, 23 }
11 {'0','1','0','0'}, 24 cout << endl;
12 {'0','1','1','0'}, 25 }
13 {'0','0','1','0'}} }; 26 }; I_Block
27 #endif

S_Block
Only paint() needs to be re-written.

13
tetris.cpp

1 #include <iostream> 0000


2 #include "SBlock_inh.h" 0000
3 using namespace std; 0011
4 int main()
0110
5 {
6 S_Block s; Something Wrong! 0000
7 s.paint(); 0000
8 s.rotate().paint(); 1111
9 s.right().paint(); 0000
10 s.right().rotate().paint();
11 return 0; 0000
12 } 0000
1111
Member function calls can not be 0000
cascaded since rotate() returns 0010
I_Block&, causing I_Block’s paint() to 0010
0010
be executed. 0010 14
tetris2.cpp

1 #include <iostream> 0000


2 #include "SBlock_inh.h" 0000
3 using namespace std;
4 int main() 0011
5 { 0110
6 S_Block s; 0000
7 s.paint(); 0100
8 s.rotate();
9 s.paint(); 0110
10 s.right(); 0010
11 s.paint(); 0000
12 s.right(); 0100
13 s.rotate();
14 s.paint(); 0110
15 return 0; 0010
16 } 0000
0000
0011
0110
15
Passing Arguments to Constructors

IBlock2.h tetris3.cpp
0000
… …
13 class I_Block{ 4 int main() 0100
14 public: 5 { 0110
15 I_Block(int xx=0,int yy=0,int ri=0): 6 S_Block s(2,0,1); 0010
x(xx),y(yy),rotate_index(ri) {} ; … 0000

0000
SBlock_inh2.h 0011
… 0110
14 class S_Block: public I_Block{ 0000
15 public:
16 S_Block(int sx=0, int sy=0, int si=0): 0000
I_Block(sx,sy,si) {} 0011
… 0110
0000
0100
0110
16 0010
Passing Arguments to Constructors (cont.)

• The colon (:) in line 14 of SBlock_inh2.h indicates inheritance.

• Keyword public indicates the type of inheritance.

• As a derived class (formed with public inheritance), S_Block inherits all the
members of class I_Block, except for the constructor—each class provides its
own constructors that are specific to the class.

• Destructors, too, are not inherited

• The constructor introduces base-class initializer syntax, which uses a member


initializer to pass arguments to the base-class constructor.

14 class S_Block: public I_Block{


15 public:
16 S_Block(int sx=0, int sy=0, int si=0):
I_Block(sx,sy,si) {}
17
Error Accessing private Members of
Base Class
IBlock3.h SBlock_inh2.h
… 17 void paint() {
32 private: 18 for(int i=0;i<4;++i)
33 int rotate_index; 19 {
34 int x, y; 20 for(int j=0;j<x;++j) cout << ' ';
… 21 for(int j=0;j<4;++j)
22 cout << S_arr[rotate_index][i][j];
23 cout << endl;
24 }
25 cout << endl;
26 }

In file included from tetris.cpp:2:


IBlock3.h: In member function 'void S_Block::paint()':
IBlock3.h:34: error: 'int I_Block::x' is private
SBlock_inh2.h:20: error: within this context
IBlock3.h:33: error: 'int I_Block::rotate_index' is private
SBlock_inh2.h:22: error: within this context
*** [tetris.o] Error code 1 18
Error Accessing private Members of
Base Class
IBlock4.h
… 0000
32 protected: 0100
33 int rotate_index; 0110
34 int x, y; 0010

0000
0000
0011
0110
0000
0000
0011
0110
0000
0100
0110
19
0010
Accessing private Members of Base Class

• The compiler generates errors because base class I_Block’s data members are
private—derived class S_Block’s member functions are not allowed to
access base class I_Block’s private data.

• The errors in derived class could have been prevented by using the get member
functions inherited from base class.

20
private Members

• A derived class can access the non-private members of its base


class.

• Base-class members that should not be accessible to the member


functions of derived classes should be declared private in the base
class.

• A derived class can change the values of private base-class


members, but only through non-private member functions provided
in the base class and inherited into the derived class.

21
protected Members

• A base class’s public members are accessible anywhere.

• A base class’s private members are accessible only within its body
and to the friends of that base class.

• Using protected access offers an intermediate level of protection


between public and private access.

• Derived-class member functions can refer to public and


protected members of the base class simply by using the member
names.

22
protected Members (cont.)

• When a derived-class member function redefines a base-class member


function, the base-class member can be accessed from the derived class
by preceding the base-class member name with the base-class name
and the binary scope resolution operator (::).

• A base class’s protected members can be accessed by members and


friends of the base class and by members and friends of any
classes derived from that base class.

• Objects of a derived class also can access protected members in


any of that derived class’s indirect base classes

23
Fake main Function Through
Inheritance
class A {
public:
A(int aa, int bb): x(aa), y(bb) { }
private:
int x,y; fake_main.cpp:5: error: 'int A::x' is private
}; fake_main.cpp:10: error: within this context
class B : public A { fake_main.cpp:5: error: 'int A::y' is private
public: fake_main.cpp:10: error: within this context
B(int a, int b): A(a,b) { }
void fake_main() { cout << x << '\t' << y << endl; }
};
int main()
{
B b(1,2);
b.fake_main();
}
24
Constructors and Destructors in Derived
Classes

• Instantiating a derived class object begins a chain of


constructor calls in which the derived class constructor, before
performing its own tasks, invokes its direct base class’s
constructor either explicitly (via a base class member
initializer) or implicitly (calling the base class’s default
constructor).
• If the base class is derived from another class, the base class
I constructor is required to invoke the constructor of the next
class up in the hierarchy, and so on.
• The last constructor called in this chain is the constructor of
the class at the base of the hierarchy, whose body actually
S A finishes executing first.
• The original derived-class constructor’s body finishes
executing last.

25
Constructors and Destructors in Derived
Classes (cont.)
• When a derived class object is destroyed, the program calls that
object’s destructor.
• This begins a chain (or cascade) of destructor calls in which the
derived-class destructor and the destructors of the direct and
indirect base classes and the classes’ members execute in reverse of
the order in which the constructors executed.
I
• When a derived class object’s destructor is called, the destructor
performs its task, then invokes the destructor of the next base class
up the hierarchy.
S A • This process repeats until the destructor of the final base class at the
top of the hierarchy is called.
• Then the object is removed from memory.

26
Constructors and Destructors in Derived
Classes (cont.)
• Base-class constructors, destructors and overloaded assignment
operators are not inherited by derived classes.

• Derived-class constructors, destructors and overloaded assignment


operators can call base-class constructors, destructors and overloaded
assignment operators.

27
Constructors and Destructors in Derived
Classes with Composition

• Suppose that we create an object of a derived class where both the base
class and the derived class contain (via composition) objects of other
classes. When an object of that derived class is created, first the
constructors for the base class’s member objects execute, then the base
class constructor executes, then the constructors for the derived class’s
member objects execute, then the derived class’s constructor executes.

• Destructors for derived class objects are called in the reverse of the
order in which their corresponding constructors are called.

28
Sequence of Constructors and Destructors

#include <iostream> class D {


using namespace std; public: D() {cout << "D ctor" << endl;}
class G { ~D() {cout << "D dtor" << endl;}
public: G() {cout << "G ctor" << endl;} G objG;
~G() {cout << "G dtor" << endl;} };
}; class E: public B {
class A { public: E() {cout << "E ctor" << endl;}
public: A() {cout << "A ctor" << endl;} ~E() {cout << "E dtor" << endl;}
~A() {cout << "A dtor" << endl;} G objG;
G objG; };
}; class F: public C, public D {
class B: public A { public: F() {cout << "F ctor" << endl;}
public: B() {cout << "B ctor" << endl;} ~F() {cout << "F dtor" << endl;}
~B() {cout << "B dtor" << endl;} G objG;
G objG; };
}; int main()
class C: public A { {
public: C() {cout << "C ctor" << endl;} E objE;
~C() {cout << "C dtor" << endl;} cout << endl;
G objG; F objF;
cout << endl;
}; return 0; 29
}
Sequence of Constructors and Destructors
(cont.)
Output:
G ctor F dtor
A ctor
A G G ctor
G dtor
D dtor
B ctor G dtor
G ctor C dtor
B G C G D G E ctor G dtor
A dtor
G ctor G dtor
A ctor
E G F G G ctor
E dtor
G dtor
C ctor B dtor
G ctor G dtor
D ctor A dtor
G ctor G dtor
F ctor
30
public, protected and private
Inheritance

• When deriving a class from a base class, the base class may be
inherited through public, protected or private inheritance.

• Use of protected and private inheritance is rare, and each


should be used only with great care; we normally use public
inheritance.

• A base class’s private members are never accessible directly from a


derived class, but can be accessed through calls to the public and
protected members of the base class.

31
public, protected and private
Inheritance (cont.)

Access Specifier public protected private


in Base Class inheritance inheritance inheritance
(在爸爸裡的 (用 public 的方 (用 protected 的 (用 private 的方
type) 式繼承) 方式繼承) 式繼承)
public public in protected in private in
derived class derived class derived class

protected protected in protected in private in


derived class derived class derived class

private Hidden in Hidden in Hidden in


derived class derived class derived class
(連 private都不 (連 private都不 (連 private都不
是!) 是!) 是!)

32

You might also like