Uploaded by Shinoa

0-1 C++ Review

advertisement
EECS 204002
Data Structures 資料結構
Prof. REN-SONG TSAY 蔡仁松 教授
NTHU
C++ QUICK REVIEW
www.tutorialspoint.com/cplusplus/cpp_quick_guide.htm
2023/9/8
Data Structures © Prof. Ren-Song Tsay
2
1.2.3
History of C++
—
C is widely-used in industry because:
◦ Efficient: Support low-level features which utilize
hardware more efficiently.
◦ Flexible: Can be used to solve problem in most
application areas.
◦ Available: C Compilers are readily available for most
platforms.
C++ is an enhanced version of C
— C++ = Object-oriented paradigm + C
—
2023/9/8
Data Structures © Prof. Ren-Song Tsay
3
Review of C
2023/9/8
Data Structures © Prof. Ren-Song Tsay
7
Auto and Static Variables
—
Automatic
◦ The variable will lose its storage (and value) when the
program exits the block
—
Static
◦ The variable is initialized only once.
◦ The value can be changed during run time.
◦ The value remains until the program exits.
2023/9/8
Data Structures © Prof. Ren-Song Tsay
11
Quiz 1: Static Variables
Show
the
output
If take out
“static” what
will be the
output?
#include <stdio.h>
/* function declaration */
void func(void);
static int count = 5; /* global variable */
main() {
while(count--) {
func();
}
return 0;
}
/* function definition */
void func( void ) {
static int i = 5; /* local static variable */
i++;
printf("i is %d and count is %d\n", i,
count);
}
2023/9/8 Data Structures © Prof. Ren-Song Tsay
12
Quiz 2: Block Scope
Show
the
output
int main()
{
{
int x = 10, y = 20;
{
printf("x = %d, y = %d\n", x, y);
{
int y = 40;
x++; // Changes the outer block variable x to 11
y++; // Changes this block's variable y to 41
}
printf("x = %d, y = %d\n", x, y);
printf("x = %d, y = %d\n", x, y);
}
}
return 0;
}
2023/9/8
Data Structures © Prof. Ren-Song Tsay
13
Example: extern global variable
//file : main.cpp
// file:
int x = 100;
// auto global defined in other file
extern int x;
//static global only within a file
static int size=10;
int main()
{
func();
func.cpp
void func () {
printf(“x=%d\n”, x );
}
return 0;
}
2023/9/8
Data Structures © Prof. Ren-Song Tsay
14
typedef: a new name for a type
typedef int Integer ;
Integer x; // = int x
typedef struct Books {
char title[50];
…
} Book;
int main( ) {
Book book;
}
2023/9/8
Data Structures © Prof. Ren-Song Tsay
18
typedef Function Pointer
typedef int (*t_somefunc)(int, int);
int product(int u, int v) {
return u*v;
}
t_somefunc afunc = &product;
...
int x2 = (*afunc)(123, 456);
// call product() to calculate 123*456
2023/9/8
Data Structures © Prof. Ren-Song Tsay
19
1.2
Object
Oriented
Design
2023/9/8
Data Structures © Prof. Ren-Song Tsay
24
From C to C++
—
Data type and operations in C
—
Extend to user-defined data types?
◦ int i,j; x = i+j;
typedef struct {
double long; // Longitude of building
double lati; // Latitude of building
char* owner; // owner of the building
} building;
building A,B;
—
◦ A+B? (Data abstraction)
How to describe a house as a building with an additional
attribute of a number of rooms? (Object Inheritance)
2023/9/8
Data Structures © Prof. Ren-Song Tsay
25
1.2.1
C: Algorithmic Decomposition
Software is viewed as a process and decomposed
into steps.
— Steps are implemented as functions
—
◦ e.g., in C or Pascal
—
Data structures are a secondary concern
◦ Data is visible and accessible to potentially all steps
◦ Unclear by which function the data is manipulated
◦ No way to prevent irrelevant code to access the data
—
Difficult to reuse code
2023/9/8
Data Structures © Prof. Ren-Song Tsay
26
1.2.1
C++: Object-Oriented Decomposition
—
Software is viewed as a set of well-defined objects
that interact with each other to solve the problem.
◦ Objects are entities that contain data (local state) and operations
(functions) to perform computation and are instances of some
classes (vs. struct in C).
◦ Focus on the design of data. ← Data Structure!
—
Benefits
◦ Intuitive to develop software
◦ Easy to maintain
◦ High reusability and flexibility
2023/9/8
Data Structures © Prof. Ren-Song Tsay
27
struct V.S. class
In C, use “struct” to define custom data types
— In C++ and OOP, introduces “class” to define
custom data types
—
◦ Each class contains NOT just data but also “operations”
– With concrete data representation of the class object.
– A set of operations to manipulate object data.
– Other operations or codes cannot access the objects.
2023/9/8
Data Structures © Prof. Ren-Song Tsay
28
1.2.2
Object-Oriented Programming
C++ fully supports object-oriented programming,
including the four pillars of object-oriented
development −
Encapsulation
— Data hiding (abstraction)
— Inheritance
— Polymorphism (多型性)
—
2023/9/8
Data Structures © Prof. Ren-Song Tsay
29
The Object in OOP
Contains data and procedural elements (functions)
— Is the basic unit for computation
— Is a fundamental building block
— Each object is an instance of some type (class)
— Classes are related to each other by inheritance
relationships
—
2023/9/8
Data Structures © Prof. Ren-Song Tsay
30
1.3
Data
Abstraction and
Encapsulation
2023/9/8
Data Structures © Prof. Ren-Song Tsay
32
Data Abstraction
User manual only tells
what the player and
buttons will do
(Specification)
— No need to know how
the machine does it
(Implementation)
—
Data Encapsulation
Interact only through
buttons (PLAY, STOP
and PAUSE)
— Do not interact with
internal circuitry
— Internal representation
(circuitry) is hidden
—
2023/9/8
Data Structures © Prof. Ren-Song Tsay
33
Abstraction & Encapsulation
—
Data Abstraction: separate interface (specification)
from implementation.
◦ Public methods
◦ Private data
– Or protected data for heirs
Data Encapsulation (Information Hiding): Conceal the
implementation details. E.g., “sort” can have many different
implementations.
• Advantages:
◦ Simplification of software development
◦ Easy to test and debug
—
2023/9/8
Data Structures © Prof. Ren-Song Tsay
34
Illustrate the Difference
https://techdifferences.com/difference-between-abstraction-and-encapsulation.html
2023/9/8
Data Structures © Prof. Ren-Song Tsay
37
1.4
Basic of C++
2023/9/8
Data Structures © Prof. Ren-Song Tsay
39
C++ Basics
—
Object: a specific dog
◦ States: color, name, breed …
◦ Behaviors: wagging, barking, eating …
Class − describes the behaviors/states that object
of its type support.
— Methods − each method describes a behavior
(function).
— Instance Variables − Each variable with a value
describes a state.
—
2023/9/8
Data Structures © Prof. Ren-Song Tsay
40
1.4.1
Program Organization
—
Header files (*.h) store
declarations
—
Source files (*.cpp) store
source code
System-defined header
#ifndef _HELLO_WORLD_H_
#define _HELLO_WORLD_H_
void Hello_World(void);
// insert other declarations here
// …
#include <iostream>
#include <Hello_World.h>
void Hello_World(void)
{
std::cout << "Hello" << std::endl;
}
#endif
2023/9/8
Data Structures © Prof. Ren-Song Tsay
41
1.4.2
Scope in C++
Local scope
A name declared in a block
void Hello_World(void)
{
int a = 2;
{
int b = 3;
}
}
Class scope
Declaration associated with
a class definition
class Obj
{
Obj(void) {m_a=2; m_b=3; }
int m_a;
int m_b;
};
2023/9/8
Data Structures © Prof. Ren-Song Tsay
42
1.4.2
Scope in C++
—
Namespace scope
namespace Yahoo{
char* homePageURL;
}
namespace Google{
char* homePageURL;
}
//access
Yahoo::homePageURL=.
..
//access
Google::homePageURL=
...
http://www.cplusplus.com/doc/tutorial/namespaces/
2023/9/8
Data Structures © Prof. Ren-Song Tsay
43
1.4.2
Namespace
—
—
—
—
A mechanism to group
related variables and
functions
Access the members
using scope operator “::”
For the repeated usage
of members, use the
“using” declaration.
Avoid namespace
pollution.
namespace Google{
char* homePageURL;
}
//access
Google::homePageURL=...
using namespace Google;
//access
homePageURL=...
2023/9/8
Data Structures © Prof. Ren-Song Tsay
44
1.4.2
Scope in C++
A variable is uniquely identified by its scope and its
name
— Scenario 1: What if a local variable reuses the
name of a global variable?
Ans: use scope operator ::
— Scenario 2: A global variable is defined in file1.cpp,
but used in file2.cpp.
Ans: as in C, use extern.
2023/9/8
Data Structures © Prof. Ren-Song Tsay
45
1.4.2
Quiz: show the result
#include <iostream>
using namespace std;
namespace first
{
int x = 5;
int y = 10;
}
namespace second
{
double x = 3.1416;
double y = 2.7183;
}
int main () {
using first::x;
using second::y;
cout << x << '\n';
cout << y << '\n';
cout << first::y << '\n';
cout << second::x << '\n';
return 0;
}
2023/9/8
Data Structures © Prof. Ren-Song Tsay
46
1.4.3
Same as in
C, except ::,
new, delete,
throw, …
http://en.cppreference.com/w/cpp/language/operator_precedence
2023/9/8 Data Structures © Prof. Ren-Song Tsay
48
1.4.4
Initialization of Variables
#include <iostream>
using namespace std;
int main ()
{
int a=5;
int b(3);
int result;
// initial value: 5
// initial value: 3
// initial value undetermined
a = a + 2;
result = a - b;
cout << result;
}
return 0;
http://www.cplusplus.com/doc/tutorial/variables/
2023/9/8
Data Structures © Prof. Ren-Song Tsay
50
1.4.4
Data Declaration in C++
—
Constant variables (const):
◦ Fixed values during their lifetime.
◦ Must be initialized at the time declared
—
Enumeration types (enum):
◦ Declaring a series of integer constants
const int MAX = 500;
enum semester {SUMMER=0, FALL, SPRING};
2023/9/8
Data Structures © Prof. Ren-Song Tsay
51
1.4.4
Pointer and Reference
—
Pointer (*):
◦ the memory address of
an object
—
Reference type (&):
◦ an alternative name to
an object (C++ only).
int i = 25;
int* np; np = &i;
int i=5;
int& j=i;
i = 7;
cout << j << endl;
2023/9/8
Data Structures © Prof. Ren-Song Tsay
52
1.4.5
Comments in C++
Single line comment:
// ooxx
Multiple Line comment:
/*
ooxx
*/
2023/9/8
Data Structures © Prof. Ren-Song Tsay
56
1.4.6
I/O in C++
C
C++
#include <stdio.h>
int main(){
int x=100, y=99;
#include <iostream>
using namespace std;
int main(){
int x=100, y=99;
printf(“%d%d\n”,x,y);
scanf(“%d %d”, &x , &y);
cout << x << y << endl;
cin >> x >> y ;
return 0;}
return 0; }
2023/9/8
Data Structures © Prof. Ren-Song Tsay
57
1.4.6
I/O in C++
—
Include the system-defined header file:
#include <iostream>
◦ need to specify namespace “std”
—
Keyword “cout” + “<<“ operator:
◦ output to the standard output device.
—
Keyword “cin” + “>>“ operator:
◦ input a value to an object.
—
Keyword “endl” :
◦ Inserts a new-line(‘\n’) character.
http://www.cplusplus.com/reference/ostream/endl/?kw=endl
2023/9/8
Data Structures © Prof. Ren-Song Tsay
58
1.4.6
File I/O in C++
—
Include the system-defined header file:
#include <fstream>
◦ Namespace is ios
—
Declare file objects using the following keywords
◦ ofstream: write to file
◦ ifstream: read from file
◦ fstream: read to/write from file
—
Specify the I/O mode when opening the file
◦ ios::out, ios::in, …etc
—
Use shift operator “<<” and “>>” to write to and read
from a file.
2023/9/8
Data Structures © Prof. Ren-Song Tsay
59
1.4.6
File I/O in C++
#include <iostream>
#include <fstream>
using namespace std;
#include <iostream>
#include <fstream>
using namespace std;
int main(){
int main(){
ofstream outFile(“my.out”, ios::out);
if(! outFile) {
cout << “cannot open my.out” << endl;
return 1;
}
ifstream inFile(“my.out”, ios::in);
if(! inFile) {
cout << “cannot open my.out” << endl;
return 1;
}
int n = 50; float f = 20.3;
outFile << “n: ” << n << endl;
outFile << “f: ” << f << endl;
Int x;
while (! inFile.eof()){
inFile >> x;
cout << x << endl;
}
return 0; }
return 0; }
2023/9/8
Data Structures © Prof. Ren-Song Tsay
60
1.4.6
I/O Operator Overloading
ostream& operator <<(ostream &os, const dataType &obj);
Class Ferrari
{
public:
int W, H, L;
char* model;
}
#include <iostream>
using namespace std;
int main(){
Ferrari myCar;
cout <<“Car info:”<<endl;
cout << myCar << endl;
return 0; }
2023/9/8
Car info:
***********
Ferrari 250 GTO
W=160
H=121
L=433
***********
Data Structures © Prof. Ren-Song Tsay
61
1.4.6
I/O Operator Overloading
using namespace std;
ostream& operator <<(ostream &os, const Ferrari &obj)
{
}
os
os
os
os
os
os
<<
<<
<<
<<
<<
<<
“***********”
“Ferrari ” <<
“W=” << obj.W
“H=” << obj.H
“L=” << obj.L
“***********”
<< endl;
obj.model << endl;
<< endl;
<< endl;
<< endl;
<< endl;
2023/9/8
Data Structures © Prof. Ren-Song Tsay
62
1.4.7
Functions in C++
—
Function declaration( function prototype )
int sum( int , int );
—
Function definition
int sum( int a, int b){
return a+b;
}
—
Inline function: compiler replaces each function call using its
function body.
inline int sum( int a, int b){
return a+b;
}
http://www.cplusplus.com/doc/tutorial/functions/
2023/9/8
Data Structures © Prof. Ren-Song Tsay
63
1.4.8
Parameter Passing by Value
—
Call by value
int special_add(int a , int b)
{
a = a+5;
return a+b;
}
—
—
Object’s value is copied into function’s local storage
(storage overhead).
Any change in ‘a’ and ‘b’ won’t modify the original
copies.
2023/9/8
Data Structures © Prof. Ren-Song Tsay
64
1.4.8
Parameter Passing by Pointer
—
Call by pointer
void swapnum(int *a , int *b){
int temp=*a;
*a=*b;
*b=temp;
}
—
Any change in ‘*a’ and ‘*b’ will modify the original
objects
2023/9/8
Data Structures © Prof. Ren-Song Tsay
65
1.4.8
Parameter Passing by Reference
—
Call by reference
void swapnum(int &a, int &b)
{
int temp = a;
a = b;
b = temp;
}
2023/9/8
Data Structures © Prof. Ren-Song Tsay
66
1.4.8
Passing const arguments
The referenced arguments cannot be modified
— Any attempt for modification will cause a compile
error.
—
void func1(const dataType& a)
{
a = …; // ← Compile time error!
}
2023/9/8
Data Structures © Prof. Ren-Song Tsay
67
1.4.9
Function Overloading in C++
—
In C++, we can have the following functions:
int Max(int, int);
int Max(int, int, int);
int Max(int*, int);
int Max(float, int);
int Max(int, float);
—
In C, it’s impossible to define two functions of same function name.
2023/9/8
Data Structures © Prof. Ren-Song Tsay
68
1.4.9
Function Overloading by Signatures
C defines a function signature by function name.
— C++ defines a function signature by
—
1. Function name
2. Type & number of parameters
3. Order of parameters
2023/9/8
Data Structures © Prof. Ren-Song Tsay
69
Polymorphism in C++
Occurs when there is a hierarchy of classes and
they are related by inheritance.
— A virtual function defined in a base class is
dynamically linked to the version in a derived class
—
2023/9/8
Data Structures © Prof. Ren-Song Tsay
71
An Example
class Shape {
protected:
int width, height;
public:
Shape( int a = 0, int b = 0){
width = a; height = b;
}
virtual int area() = 0;
};
class Rectangle: public Shape {
public:
Rectangle( int a = 0, int b = 0): Shape(a, b) { }
int area () {
return (width * height);
}
};
class Triangle: public Shape {
public:
Triangle( int a = 0, int b = 0):Shape(a, b) { }
int area () {
return (width * height / 2);
}
};
2023/9/8
Data Structures © Prof. Ren-Song Tsay
72
1.4.11
Dynamic Memory Allocation in C++
—
Dynamic Memory Allocation in C
◦ malloc, delete, realloc, memset, memcopy
◦ Causes memory leak and memory fragmentation
problems
—
New dynamic memory allocation mechanism in C++
◦ Use keywords “new” and “delete”
◦ The “new” operator in C++ is more powerful than “malloc”
in C.
◦ Use ‘delete’ for pointer generated by ‘new’.
2023/9/8
Data Structures © Prof. Ren-Song Tsay
74
1.4.11
Dynamic Memory Allocation in C++
—
C
—
C++
#include <cstdio>
#include <iostream>
int main () {
int main () {
int * x = (int*) malloc ( sizeof(int) );
free(x);
int * y = new int ;
delete y ;
return 0;
// allocate an int array.
int * data = new int [10];
/* make sure you use ‘delete’ for
pointer generated by ‘new’. */
delete [] data ;
}
return 0;
}
http://www.cplusplus.com/reference/new/operator%20new[]/
2023/9/8
Data Structures © Prof. Ren-Song Tsay
75
1.4.12
Handling Exceptions
—
try-catch block
◦
◦
◦
◦
—
Exceptions are thrown by a piece of code within the try block.
Each try block is followed by zero or more catch blocks.
Each catch block is visited sequentially until the matched block is found.
Each catch block has a parameter whose type determines the type of
exception to be caught.
catch (char* e){}
◦ Catch exceptions of type char*.
—
catch (bad_alloc e){}
◦ Catch exceptions of type bad_alloc (system-defined type).
—
catch (…){}
◦ Catch all exceptions regardless of types.
http://www.cplusplus.com/doc/tutorial/exceptions/
2023/9/8 Data Structures © Prof. Ren-Song Tsay
80
1.4.12
P1.6
Example
int DivZero(int a, int b, int c){
if(a <= 0 || b <=0 || c <= 0)
throw “All parameters should be > 0”;
return a+b*c+b/c;
}
int main () {
try {
cout << DivZero(2, 0, 4) << endl;
}
catch (const char* e) {
cout << “The parameters to DivZero were 2, 0, 4" << endl;
cout << “An exception has been thrown" << endl;
cout << e << endl;
} catch (…) {
cout << “An unknown exception has been thrown" << endl;
}
return 0;
}
2023/9/8
Data Structures © Prof. Ren-Song Tsay
84
2.1
Abstract Data
Type and the
C++ Class
2023/9/8
Data Structures © Prof. Ren-Song Tsay
86
Reviews of Data Type
A data type is a collection of objects and a set of
operations that act on objects
— Fundamental data type in C++:
—
◦ char, int, float, double, …etc.
◦ Modifiers: short, long, signed, unsigned
—
Example: int data type
◦ Objects: {0, +1, -1, +2, -2, …, MAXINT, MININT}
◦ Operations: {+, -, *, /, ==, <=, …etc.}
2023/9/8
Data Structures © Prof. Ren-Song Tsay
87
Reviews of Data Type
How to group data together?
— Arrays: int x[10];
—
◦ Collection of elements of the same basic data type.
—
structs (C) and classes (C++)
◦ Collection of elements whose data types need not be the
same.
2023/9/8
Data Structures © Prof. Ren-Song Tsay
88
Abstract Data Type (ADT)
—
A data type that separates
◦ The specification of objects from their representation
◦ The specification of operation from their implementation.
—
Major advantages
◦
◦
◦
◦
Simplification
Testing and debugging
Reusability
Flexibility
2023/9/8
Data Structures © Prof. Ren-Song Tsay
89
Example
Data Type 1
Data Type 2
Objects:
int data;
Objects:
float data;
Operations:
int Value(void)
{ return data; }
Operations:
float Value(void)
{ return data; }
void Calculate(void)
{data = 100; }
void Calculate(void)
{data= exp(-10); }
2023/9/8
Data Type 3
Objects:
Type1 data;
int data2;
Operations:
int Value(void)
{ return data.Value()+data2; }
void Calculate(void)
{data. Calculate();
data2 = 128; }
Data Structures © Prof. Ren-Song Tsay
90
Object Representation?
Data Type 1
Data Type 2
Objects:
int data;
Objects:
float data;
Operations:
int Value(void)
{ return data; }
Operations:
float Value(void)
{ return data; }
void Calculate(void)
{data = 100; }
void Calculate(void)
{data= exp(-10); }
2023/9/8
Data Type 3
Objects:
Type1 data;
int data2;
Operations:
int Value(void)
{ return data.Value()+data2; }
void Calculate(void)
{data. Calculate();
data2 = 128; }
Data Structures © Prof. Ren-Song Tsay
91
Object Specification?
Data Type 1
Data Type 2
Objects:
int data;
Objects:
float data;
Operations:
int Value(void)
{ return data; }
Operations:
float Value(void)
{ return data; }
void Calculate(void)
{data = 100; }
void Calculate(void)
{data= exp(-10); }
2023/9/8
Data Type 3
Objects:
Type1 data;
int data2;
Operations:
int Value(void)
{ return data.Value()+data2; }
void Calculate(void)
{data. Calculate();
data2 = 128; }
Data Structures © Prof. Ren-Song Tsay
92
Operation Specification?
Data Type 1
Data Type 2
Objects:
int data;
Objects:
float data;
Operations:
int Value(void)
{ return data; }
Operations:
float Value(void)
{ return data; }
void Calculate(void)
{data = 100; }
void Calculate(void)
{data= exp(-10); }
2023/9/8
Data Type 3
Objects:
Type1 data;
int data2;
Operations:
int Value(void)
{ return data.Value()+data2; }
void Calculate(void)
{data. Calculate();
data2 = 128; }
Data Structures © Prof. Ren-Song Tsay
93
Operation Implementation?
Data Type 1
Data Type 2
Objects:
int data;
Objects:
float data;
Operations:
int Value(void)
{ return data; }
Operations:
float Value(void)
{ return data; }
void Calculate(void)
{data = 100; }
void Calculate(void)
{data= exp(-10); }
2023/9/8
Data Type 3
Objects:
Type1 data;
int data2;
Operations:
int Value(void)
{ return data.Value()+data2; }
void Calculate(void)
{data. Calculate();
data2 = 128; }
Data Structures © Prof. Ren-Song Tsay
94
A Software that uses ADTs
Type3
Obj3
Type1
Obj1
Type2
Obj2
double Calculate1(void);
double Calculate2(void);
double Calculate3(void);
double Calculate1(void)
{ Obj1.Calculate();
Obj2.Calculate();
return (double)Obj1.Value()+
(double)Obj2.Value();}
double Calculate2(void)
{ Obj2.Calculate();
Obj3.Calculate();
return (double)Obj2.Value()+
(double)Obj3.Value();}
2023/9/8
Data Structures © Prof. Ren-Song Tsay
95
Introduction to C++ Class
—
C++ provides new mechanism, class, to support data
abstraction and encapsulation.
// In the header file Rectangle.h
#ifndef RECTANGLE_H
#define RECTANGLE_H
class Rectangle {
public: // the following members are public
// the next four members are member functions
Rectangle ( );
// constructor
~Rectangle( );
// destructor
int GetHeight ( ); // return the height of the rectangle
int GetWidth ( );
// return the width of the rectangle
private: // the following members are private
// the following members are data member
int xLow, yLow, height, width;
// (xLow, yLow) are the coordinates of the bottom left corner of rec.
};
#endif
2023/9/8
Data Structures © Prof. Ren-Song Tsay
98
Class Architecture
—
—
A class name: (e.g., Rectangle)
Data members:
◦ The data that makes up the class (e.g., xLow, yLow, height, width)
—
Member functions:
◦ The set of operations that apply to the objects (e.g., GetHeight(),
GetWidth() )
—
Levels of program access (data encapsulation):
◦ public: data member (function) can be accessed from anywhere in
the program.
◦ private: data member (function) can be accessed only within its
class or by a friend class
◦ protected: data member (function) can be accessed only within its
class, by a friend class or from its subclass (class inheritance)
2023/9/8
Data Structures © Prof. Ren-Song Tsay
99
2.1.2
Data Abstraction and Encapsulation
// In the header file Rectangle.h
#ifndef RECTANGLE_H
Data abstraction
#define RECTANGLE_H
Implementation?
(Specification)
class Rectangle {
public: // the following members are public
// the next four members are member functions
Rectangle ( );
// constructor
~Rectangle( );
// destructor
int GetHeight ( ); // return the height of the rectangle
int GetWidth ( ); // return the width of the rectangle
private: // the following members are private
// the following members are data member
int xLow, yLow, height, width;
// (xLow, yLow) are the coordinates of the bottom left corner of rec.
};
Data encapsulation
#endif
2023/9/8
Data Structures © Prof. Ren-Song Tsay
100
Data Abstraction
Specification is placed in header file (e.g.,
Rectangle.h)
— Implementation is placed in source file (e.g.,
Rectangle.cpp)
—
// In the source file Rectangle.cpp
#include “Rectangle.h”
/* The prefix ”Rectangle::” identifies GetHeight() and GetWidth() are member
function of class Rectangle. It is required because the member functions are
implemented outside the class definition*/
int Rectangle::GetHeight() {return height;}
int Rectangle::GetWidth() {return width;}
2023/9/8
Data Structures © Prof. Ren-Song Tsay
101
Class Usage
// In a source file main.cpp
#include <iostream>
#include “Rectangle.h”
main() {
Rectangle r, s;
// r and s are objects of class “Rectangle”
Rectangle *t = &s;
// t is a pointer to class object s
.
.
// use “.” operator to access members of class objects.
// use “®“ operator to access members of class objects through pointers.
If ( r.GetHigh ( ) * r.GetWidth ( ) > t®GetHeight ( ) * t®GetWidth ( ) )
cout << “r”;
else cout << “s”;
cout << “has the greater area “ << endl;
}
2023/9/8
Data Structures © Prof. Ren-Song Tsay
102
Data Encapsulation
C++
C
class Foo{
private:
int x;
public:
int y;
};
struct Foo{
int main(void){
Foo obj1 ;
obj1.x = 11; // compile ERROR
obj1.y = 22; // access y
}
int main(void){
struct Foo obj1 ;
obj1.x = 11; // access x
obj1.y = 22; // access y
}
int x;
int y;
};
2023/9/8
Data Structures © Prof. Ren-Song Tsay
103
Constructors and Destructors
// In the source file Rectangle.cpp
#include “Rectangle.h”
// constructor
Rectangle::Rectangle (void)
{
xLow = 0; yLow = 0;
height = 1; width = 1;
}
// destructor
Rectangle::~Rectangle (void)
{
xLow = yLow = height = width = 0;
}
int Rectangle::GetHeight() {return height;}
int Rectangle::GetWidth() {return width;}
2023/9/8
Data Structures © Prof. Ren-Song Tsay
104
Constructors
—
—
—
—
—
—
A member function to initialize the data members.
Constructor (if defined) is invoked when an object is
created, otherwise only the memory of data member is
allocated.
Must be declared as a public member.
Must have the same name as the class.
No return type or return value.
A class can have multiple constructors, as long as their
signature (the parameters they take) are not the same.
2023/9/8
Data Structures © Prof. Ren-Song Tsay
105
Type of Constructors
—
Default constructor
◦ A constructor with no arguments
Rectangle ( );
—
// default constructor
Augmented constructor
◦ A constructor with arguments
Rectangle (int, int, int, int);
—
// augmented constructor
Copy constructor
◦ Must be specified if the STL containers are used to store
your class object.
Rectangle (const Rectangle&); // copy constructor
2023/9/8
Data Structures © Prof. Ren-Song Tsay
106
Augmented Constructor
—
Implementation
Rectangle::Rectangle (int x, int y, int h, int w)
{
xLow = x; yLow = y;
height = h; width = w;
}
—
May use member initialization list (more efficient)
Rectangle::Rectangle ( int x, int y, int h, int w )
: xLow (x), yLow (y), height (h), width (w)
{}
2023/9/8
Data Structures © Prof. Ren-Song Tsay
107
Copy Constructor
—
Implementation
Rectangle::Rectangle (const Rectangle& _src)
{
xLow = _src. xLow;
yLow = _src. yLow;
height = _src. height ;
width = _src. width ;
}
2023/9/8
Data Structures © Prof. Ren-Song Tsay
108
A Constructor Example
// In a source file main.cpp
#include <iostream>
#include “Rectangle.h”
main() {
// r1 and r2 are initialized using default constructor
Rectangle r1;
Rectangle *r2 = new Rectangle;
// r3 and r4 are initialized using augmented constructor
Rectangle r3(1, 3, 6, 6);
Rectangle *r4 = new Rectangle(0, 0, 3, 4);
// r5 is initialized using r4 through copy constructor
Rectangle r5(*r4);
}
2023/9/8
Data Structures © Prof. Ren-Song Tsay
109
Frequently Made Mistakes
—
To specify an augmented constructor, one MUST
also specify a default constructor.
/* The following statement results in a compile time error if an augmented
constructor is defined but default constructor is missing */
Rectangle t;
—
Possible solution: use default value for arguments.
Rectangle::Rectangle ( int x = 0, int y = 0, int h = 0, int w = 0 )
: xLow (x), yLow (y), height (h), width (w)
{}
2023/9/8
Data Structures © Prof. Ren-Song Tsay
110
Destructor
—
—
—
—
—
—
—
A member function to delete data members when the
object disappears.
The destructor is automatically invoked when a class
object is out of scope or is deleted.
Must be declared as a public member.
Must have the same name as the class with the prefix
“~”.
No return type or return value.
Take no arguments.
Only one destructor for a class.
2023/9/8
Data Structures © Prof. Ren-Song Tsay
111
Operator Overloading
—
C++ can define customized “operators” for a class
object.
// In a source file main.cpp
#include <iostream>
#include “Rectangle.h”
main() {
Rectangle r1, r2(1, 3, 6, 6), r3(0, 0, 3, 4);
r1 = r2; // compile time error, no operator “=” is defined for Rectangle class
if(r2==r3) // compile time error, no operator “==” is defined for Rectangle class
{…}
}
2023/9/8
Data Structures © Prof. Ren-Song Tsay
113
Operator Overloading
// In the header file Rectangle.h
#ifndef RECTANGLE_H
#define RECTANGLE_H
class Rectangle {
public:
Rectangle ( ); // constructor
~Rectangle( ); // destructor
int GetHeight ( );// return the height of the rectangle
int GetWidth ( ); // return the width of the rectangle
// the function prototype for operator overloading is fixed
bool operator== (const Rectangle&);
// overloading operator “==”
Rectangle& operator= (const Rectangle&); // overloading operator “=”
private:
int xLow, yLow, height, width;
};
#endif
http://en.wikipedia.org/wiki/Operator_overloading
2023/9/8
Data Structures © Prof. Ren-Song Tsay
114
Operator Overloading
bool Rectangle::operator == (const Rectangle& _rhs)
{
if (this == &_rhs) return true;
if ((xLow == _rhs.xLow) && (yLow == _rhs.yLow) &&
(height == _rhs.height) && (width == _rhs.width) ) return true;
else return false;
}
Rectangle& Rectangle::operator = (const Rectangle& _rhs)
{
Important Note!!!
if (this == &_rhs) return (*this);
“this” is a reserved keyword
xLow = _rhs. xLow;
indicating a pointer to the class
yLow = _rhs. yLow;
object itself
height = _rhs. height ;
width = _rhs. width ;
return (*this);
}
2023/9/8
Data Structures © Prof. Ren-Song Tsay
115
I/O Operator Overloading
ostream& operator <<(ostream &os, const Rectangle &r);
{
// need to implement additional GetX() and GetY() member functions
os << “Position is : “ << r.GetX() << “ “;
os << r.GetY() << endl;
os << “Height is: “ << r.GetHeight() << endl;
os << “Width is: “ << r.GetWidth() << endl;
return os;
}
main() {
Rectangle r1, r2(1, 3, 6, 6), r3(0, 0, 3, 4);
std::cout << r1 << r2 << r3 << std::endl;
}
Ref: C++ Primer 5th chapter 14
2023/9/8
Data Structures © Prof. Ren-Song Tsay
116
3.1
Templates in
C++
2023/9/8
Data Structures © Prof. Ren-Song Tsay
120
3.1
Template in C++
A mechanism to parameterize the target data type
and instantiate it to a proper data type at compile
time.
— Using the keyword template followed by parameter
type list <typename T> or <class T>.
—
2023/9/8
Data Structures © Prof. Ren-Song Tsay
121
3.1.1
Function Template
Ordinary function
Template function
int sum(int * data, const int SIZE)
{
int sum=0 ;
for( int i =0; i < SIZE; i++)
{
sum += data[i];
}
return sum;
}
template < class T >
T sum(T * data, const int SIZE)
{
T sum=0 ;
for( int i =0; i < SIZE; i++)
{
sum += data[i];
}
return sum;
}
2023/9/8
Data Structures © Prof. Ren-Song Tsay
122
3.1.1
Function Template
The compiler will insert the code with proper data
type at compile time.
— The source code is visible to everyone!
—
int main(){
int data1[100] = …;
sum( data1 ) ;
After compiling
int main(){
int data1[100] = …;
{int sum=0 ;
for( int i =0; i < SIZE; i++ ){
sum += data1[i];}}
float data2[100] = …. ;
{ float sum=0 ;
for(int i =0; i < SIZE; i++){
sum += data2[i];}}
float data2[100] = …;
sum( data2 ) ;
}
source code
}
2023/9/8
Data Structures © Prof. Ren-Song Tsay
123
3.1.2
P3.4
The Class Bag Containing int
class Bag
{
public:
Bag(int bagCapacity = 10);
~Bag();
// Constructor
// Destructor
int Size() const;
// Return the number of elements
bool IsEmpty() const;
// Check if bag is empty
int Element() const;
// Return an element in the bag
void Push(const int);
void Pop()
// Insert an integer into the bag
// Delete an integer from the bag
private:
int *array;
int capacity;
int top;
};
// Integer array that stores the data
// Capacity of array
// Position of top element
2023/9/8
Data Structures © Prof. Ren-Song Tsay
124
3.1.2
P3.5
Implement Bag Operations
Bag::Bag( int bagCapacity):capacity( bagCapacity ) {
if(capacity < 1) throw “Capacity must be > 0”;
array = new int [ capacity ];
top = -1;
}
Bag::~Bag(){ delete [] array; }
inline int Bag::Size() const { return top + 1; }
inline bool Bag::IsEmpty() const { return Size() == 0; }
inline int Bag::Element() const {
if(IsEmpty()) throw “Bag is empty”;
return array [0]; // Always return the first element
}
void Bag::Push(const int x) {
if(capacity == top+1) ChangeSize1D(array,capacity,2*capacity);
capacity *= 2;
array[++top]=x;
}
void Bag::Pop( ) {
if(IsEmpty()) throw “Bag is empty, cannot delete”;
int deletePos = top / 2; // Always delete the middle element
copy (array+deletePos+1, array+top+1, array+deletePos);
top--;
}
2023/9/8 Data Structures © Prof. Ren-Song Tsay
125
3.1.2
P3.6
Define Class Template Bag
template<class T>
class Bag
{
public:
Bag(int bagCapacity = 10); // Constructor
~Bag();
// Destructor
int Size() const;
// Return the number of elements
bool IsEmpty() const;
// Check if bag is empty
T& Element() const;
// Return an element in the bag
void Push(const T&);
void Pop()
// Insert an element into the bag
// Delete an element from the bag
private:
T *array;
int capacity;
int top;
};
// Data array
// Capacity of array
// Position of top element
2023/9/8
Data Structures © Prof. Ren-Song Tsay
126
3.1.2
P3.7
Implementation of Some Bag Operations
template<class T>
Bag<T>::Bag( int bagCapacity):capacity( bagCapacity ) {
if(capacity < 1) throw “Capacity must be > 0”;
array = new T [ capacity ];
top = -1;
}
template<class T>
void Bag<T>::Push(const T& x) {
if(capacity == top+1) ChangeSize1D(array,capacity,2* capacity);
capacity *= 2;
array[++top]=x;
}
template<class T>
void Bag<T>::Pop() {
if(IsEmpty()) throw “Bag is empty, cannot delete”;
int deletePos = top/2; // Always delete the middle emelent
copy (array+deletePos+1, array+top+1, array+deletePos);
array[top--].~T();
2023/9/8 Data Structures © Prof. Ren-Song Tsay
}
127
3.1.2
An Example Using Template
int main() {
// T is instantiated as int
Bag<int> Bag1;
Bag1.Push(10);
…
// T is instantiated as MyData
Bag<MyData> Bag2;
Bag2.Push(MyData());
…
}
2023/9/8
Data Structures © Prof. Ren-Song Tsay
128
3.4
Subtyping and
Inheritance in
C++
2023/9/8
Data Structures © Prof. Ren-Song Tsay
130
Object Inheritance
An object A could be used to define another object B.
— Both objects and operations of A are automatically
inherited by B.
—
◦ house can inherit from building
• Advantages:
◦ Simplification of software development
◦ Easy to test and debug
◦ Reusability
◦ Flexibility
2023/9/8
house
Building
Data Structures © Prof. Ren-Song Tsay
131
C++ Inheritance
—
Define a class in terms of another class
◦ easier to create and maintain an application.
The existing class = base class,
the new class = derived class.
— The derived class is a base class
—
derived
base
◦ dog IS-A mammal
—
A class can be derived from more than one classes,
i.e. inherit data and functions from multiple base
classes.
2023/9/8
Data Structures © Prof. Ren-Song Tsay
132
Process Geometry
—
If to develop a program to process various types of
geometry.
…
Triangle
—
Rectangle
Trapezoid
Operations on these primitives:
◦ Get number of vertices.
◦ Calculate the area of the primitive.
◦ Check whether it is convex or not.
2023/9/8
Data Structures © Prof. Ren-Song Tsay
133
Implement Using Classes
Triangle
class Triangle {
public:
Triangle ( ){
m_VN = 3;
mp_V = new Point [m_VN];
}
~Triangle ( ){
delete [] mp_V;
mp_V = NULL;
}
double CalArea ( );
bool isConvex();
int vtxNum() { return m_VN; }
private:
int m_VN;
Point* mp_V;
};
class Rectangle {
public:
Rectangle ( ){
m_VN = 4;
mp_V = new Point [m_VN];
}
~Rectangle( ){
delete [] mp_V;
mp_V = NULL;
}
double CalArea ( );
bool isConvex();
int vtxNum() { return m_VN; }
private:
int m_VN;
Point* mp_V;
};
2023/9/8
Data Structures © Prof. Ren-Song Tsay
Rectangle
134
What’s the Problem?
Duplicated codes in both classes!
— If need to design 100 or more types of geometry?
— If need to add another “common”
data member or function?
— Will need to maintain all the classes!
—
2023/9/8
Data Structures © Prof. Ren-Song Tsay
135
Polygon Base Class
Polygon is an abstract type of geometry.
— Triangle and rectangle are special polygons.
— But how do we let the triangle and rectangle
classes share the same code by using polygon?
— Don’t worry! C++ will be your lifesaver!
—
2023/9/8
Data Structures © Prof. Ren-Song Tsay
136
Class Inheritance in C++
A mechanism to relate one class object to another
one.
— Define a “IS-A” relationships between objects.
—
B
◦ Type B IS-A data type of Type A if B is a specialized
version of A and A is more general than B, e.g., Triangle
IS-A Polygon and Rectangle IS-A Polygon.
A
Members (data and functions) in Type A are
implicitly copied to Type B.
— Reusability of code
—
2023/9/8
Data Structures © Prof. Ren-Song Tsay
137
3.4
Class Diagram of Inheritance
class
Polygon
Base class
“IS-A” relationships
class
Triangle
class
Rectangle
Derived class
2023/9/8
Data Structures © Prof. Ren-Song Tsay
138
3.4
Inherit the Polygon Class
class Polygon {
public:
Polygon ( ){
m_VN = 0;
mp_V = NULL;
}
~Polygon ( ){
delete [] mp_V;
mp_V = NULL;
}
double CalArea ( ) { return 0.0;}
bool isConvex() { return true; }
int vtxNum() { return m_VN; }
protected:
int m_VN;
Point* mp_V;
};
class Triangle: public Polygon {
public:
Triangle ( ){
m_VN = 3;
mp_V = new Point [m_VN];
}
~Triangle ( ){}
double CalArea ( );
};
Triangle
Class Rectangle: public Polygon {
public:
Rectangle ( ){
m_VN = 4;
Rectangle
mp_V = new Point [m_VN];
}
~Rectangle ( ){}
double CalArea ( );
}; 2023/9/8 Data Structures © Prof. Ren-Song Tsay
139
Access Specifier of Inheritance
“class Triangle: public Polygon” indicates the
triangle class inherits all the non-private members
(data and functions) from Polygon
— The access specifier could be public, protected
and private.
—
https://www.learncpp.com/cpp-tutorial/115-inheritance-and-access-specifiers/
2023/9/8
Data Structures © Prof. Ren-Song Tsay
140
Access Specifier: public
Base Class
Derived Class
class Triangle : public Polygon
{
class Polygon
{
private:
int x;
protected:
X
private:
//CANNOT ACCESS private
member of base class
protected:
Int y;
int y;
public :
public :
Int z;
int z;
};
};
2023/9/8
Data Structures © Prof. Ren-Song Tsay
141
Access Specifier: protected
Base Class
Derived Class
class Triangle : protected Polygon
{
class Polygon
{
private:
int x;
protected:
X
private:
protected:
Int y;
int y;
Int z;
public :
int z;
public :
};
};
2023/9/8
Data Structures © Prof. Ren-Song Tsay
142
Access Specifier: private
Base Class
Derived Class
class Triangle : private Polygon
{
class Polygon
{
private:
int x;
X
private:
Int y;
protected:
Int z;
int y;
public :
int z;
};
protected:
public :
};
2023/9/8
Data Structures © Prof. Ren-Song Tsay
143
Specialization
—
Some members (data and functions) are specialized
in different class.
◦ Triangle and Rectangle use different area calculation, e.g.,
specialized CalArea() function.
Put these non-common members in private block of
base class. Derived class thus cannot access these
members (Optional)
— Re-declare the members (data and functions) in the
derived class. (overriding)
—
2023/9/8
Data Structures © Prof. Ren-Song Tsay
144
Overriding
class Polygon {
public:
…
double CalArea ( ) { return 0.0;}
…
};
class Triangle : public Polygon {
public:
…
// overriding CalArea function
double CalArea () {
// calculate triangle area
}
};
Class Rectangle : public Polygon {
public:
…
// overriding CalArea function
double CalArea ( ){
// calculate rectangle area
/* if you want to access the
original base class function*/
Polygon::CalArea();
}
};
2023/9/8
Data Structures © Prof. Ren-Song Tsay
145
Overloading v.s. Overriding
—
Function overloading: (超載)
◦ Two or more functions with the same name but different
signatures in the same scope or one in base class and
another in derived class.
—
Function overriding:(覆蓋)
◦ A different implementation of the same function in the
inherited class.
◦ Functions would have the same signature, but different
implementation.
◦ Only exist in class inheritance.
http://www.codeproject.com/Articles/16407/METHOD-Overload-Vs-Overriding
2023/9/8
Data Structures © Prof. Ren-Song Tsay
146
Initialization
—
The order of calling constructors:
Base class
—
2nd derived
class
Last derived
class
The order of calling destructors:
Last derived
class
—
1st derived
class
2nd derived
class
1st derived
class
Base class
Use Initialization Lists to initialize base class in
derived class via constructor
2023/9/8
Data Structures © Prof. Ren-Song Tsay
147
A Constructor Example
class Foo
{
public:
Foo() { std::cout << "Foo's
constructor" << std::endl; }
};
class Bar: public Foo
{
public:
Bar() { std::cout << "Bar's
constructor" << std::endl; }
};
int main(){
Bar bar;
}
Output:
Foo's constructor
Bar's constructor
2023/9/8
Bar
Foo
Data Structures © Prof. Ren-Song Tsay
148
Polymorphism (多態性)
A mechanism allow you to manipulate different
objects through the common interface.
— Why not function overloading?
—
class Foo
{
public:
char* getName()
{ return “foo”; }
};
class Bar: public Foo
{
public:
char* getName()
{ return “Bar”; }
};
2023/9/8
class Car: public Foo
{
public:
char* getName()
{ return “Car”; }
};
Data Structures © Prof. Ren-Song Tsay
151
Review Function Overloading
int main(){
Foo myFoo;
Bar myBar;
Car myCar;
processObj(Foo _obj)
{… _obj.getName()…}
processObj(Bar _obj)
{… _obj.getName()…}
processObj(myFoo);
processObj (myBar);
processObj (myCar);
processObj(Car _car)
{… _obj.getName()…}
}
Each function performs the same algorithm and
works only on different data type of object .
— Duplicated code.
— What if need to modify the algorithm?
—
2023/9/8
Data Structures © Prof. Ren-Song Tsay
152
Polymorphism
class Foo
{
public:
char* getName()
{ return “foo”; }
};
class Bar : public Foo
{
public:
char* getName()
{ return “Bar”; }
};
int main(){
Foo* myFoo = new Foo;
Foo* myBar = new Bar;
Foo* myCar = new Car;
class Car : public Foo
{
public:
char* getName()
{ return “Car”; }
};
processObj(Foo* _obj)
{… _obj->getName()…}
processObj(myFoo);
processObj(myBar);
processObj(myCar);
}
2023/9/8
Data Structures © Prof. Ren-Song Tsay
153
Polymorphism
class Foo
{
public:
char* getName()
{ return “foo”; }
};
class Bar : public Foo
{
public:
char* getName()
{ return “Bar”; }
};
int main(){
Foo* myFoo = new Foo;
Foo* myBar = new Bar;
Foo* myCar = new Car;
class Car : public Foo
{
public:
char* getName()
{ return “Car”; }
};
processObj(Foo* _obj)
{… _obj->getName()…}
processObj(myFoo);
processObj(myBar);
processObj(myCar);
}
2023/9/8
Data Structures © Prof. Ren-Song Tsay
154
Polymorphism
Function Overloading
—
Data type is determined in
compiler time.
int main(){
Foo myFoo;
Bar myBar;
Car myCar;
Dynamic Binding
—
Data type is determined in run
time.
int main(){
Foo* myFoo = new Foo;
Foo* myBar = new Bar;
Foo* myCar = new Car;
processObj (myFoo);
processObj (myBar);
processObj (myCar);
}
processObj(myFoo);
processObj(myBar);
processObj(myCar);
}
Use the keyword “virtual” as a
prefix of your member function
2023/9/8
Data Structures © Prof. Ren-Song Tsay
155
Download