Abstract Data Types (ADT) and C++ Classes 1-15-2013 Abstract Data - - PowerPoint PPT Presentation
Abstract Data Types (ADT) and C++ Classes 1-15-2013 Abstract Data - - PowerPoint PPT Presentation
Abstract Data Types (ADT) and C++ Classes 1-15-2013 Abstract Data Types (ADT) & UML C++ Class definition & implementation constructors, accessors & modifiers overloading operators friend functions HW#1 posted
Abstract Data Types (ADT) & UML C++ Class definition & implementation
constructors, accessors & modifiers overloading operators friend functions
HW#1 posted – due: Tuesday, 1/22 Quiz Thursday, 1/24
FAQ 5.14 What is an abstraction and why is it important? FAQ 5.15 Should abstractions be user-centric or developer-centric? An abstraction is a simplified vew of an object in the user’s own vocabulary. In OO and C++, an abstraction is the simplest interface to an
- bject that provides all the features and
services the intended users expect. User-centric. Focus on the user’s point of view.
Computes what each employee should be paid for a day of work. Reads a file containing start and stop times for each employee. Then calculates and saves the pay amounts to another file. int runPayCalculator (const char csInputFileName[], const char csOutputFileName[]) Sample input: 510 + 24601 990 - 24601 Sample output 24601 96
int runPayCalculator (const char csInputFileName[], const char csOutputFileName[]) Algorithm: call computeHours and then computeAndWritePay Data structure: The number of hours worked by each employee is stored in an array indexed by the possible employee
- numbers. This array is of size MAX_EMPLOYEE_NUMBER
+ 1, where MAX_EMPLOYEE_NUMBER is a global constant
In a well-designed modular program, software components should satisfy the following two properties:
- 1. Each component performs one well
ll-def defined ned task
- sk. (i.e. “cohesion”)
- 2. Each component is as indep
ndependen ndent as possible from the others. (i.e. loosely coupled”)
- 1. Easier to understand; little redundant code.
- 2. Facilitates software reuse.
- 3. Easier to implement.
- 4. Easier to test.
- 5. Easier to modify.
Independence of modules is typically achieved by “information hiding” (which can be achieved by “encapsulation”). Procedural Abstraction
Use of a function depends on its purpose (what it
does) but not on its implementation (how it does it).
FAQ 5.18 What’s the value of separating interface from implementation? It’s a key to eliminating the ripple effect when a change is made.
Class designer/implementer
- designs & implements a class
vs. Client programmer
- uses a class for an application
vs. End-user
- uses the application
Procedural Abstraction (Algorithm) Data Abstraction (Data)
An Abstract stract Data ta Type (ADT) is a specification of a set of data and a set of operations that can be performed on the data. examples: String Circle List Dice Dictionary Song Student Telephone Directory Time Complex number
In C++, a class represents an ADT. An “instance” of a class is a specific object which is created, and the data members are filled in with values (possibly default values). Objects are created with a specialized member function called a “constructor”. An instance of a class is destroyed (recycled) with a specialized member function called a “destructor”
Circle
constructor(s): Circle(int,int), Circle(float,int,int); float computeArea(); float getRadius(); void setRadius(float); // etc.
Type name Public interface
An ADT is a contract between
The interface designer and ... The coder of a class that implements the
interface
Prec econ
- ndition:
dition: any assumption/constraint on the method data before the method begins execution Postcond tcondition: ition: describes result of executing the method
A C++ program is a collection of functions and classes. A class represents a set of objects that have common properties. A class is a template for creating objects. A class represents a type.
Type determines the set of values an object may
have.
Type determines the operations that can be
performed on those values.
In C++ there are two kinds of types:
Primitive or build-in types User Defined or class types
A class consists of members
Data members – also called data fields or
attributes
Member functions – also called operators,
functions or methods
Data members are also sometimes called instance variables because each object (instance of a class) contains them. Data members may be either primitive or class types.
private instance variables: private float radius; private Point center; public methods: constructor(s) accessor methods (get) mutator methods (set) float computeArea() … etc.
Represent a 2D “point” Data: (x , y) coordinates, integer values Methods: create a point with coordinates (0,0) create a point with coordinates (x,y), get the x coordinate of a point, get the y coordinate of a point, draw a point erase a point move a point etc.
Unified Modeling Language (UML) is a standard diagram notation for describing a class
Instance
- f Person
Field values Class name Field signatures: type and name Method signatures: name, argument types, result type
Point
constructor(s): Point(int,int), Point(); // default (0,0) int getX(); int getY(); // etc.
Type name Public interface
private instance variables: private int xCoordinate private int yCoordinate public methods: constructor(s) accessor methods (get) mutator methods (set) … etc.
Class members that are declared in the public section of a class definition are accessible to all functions (inside or outside) the class. Class members that are declared in the private section of a class definition are accessible only to functions that are members of the class. Generally we want the operators (member functions) visible to the users of the class.
Thus they are declared public.
Generally we want to keep the implementation details (data members) hidden from the users of the class
Thus they are declared private.
A constructor is a member function that initializes the data members of an object when the object is
cr crea eate ted. d.
Note the use of
initializat ialization ion lists (more re effici cien ent than assignmen nment t statement ments) s)
cl class s Point int { public: lic: Point( nt(int nt i, , int j) : x( x(i), y( y(j) { } } Point() nt() : x(0) 0), y(0) 0) { } } private vate: int x; x; int y; y; }
A modifier function provides the ability to modify the value of a private data member vo void d setX tX(in int newX wX) ) { x = = newX wX; ; } An accessor function provides the ability to read the value of a private data member, without changing it (note use of “const”)
in int ge getX() () co const { return n x; }
class Point { public: Point(int i, int j) : x(i), y(j) { } Point() : x(0), y(0) { } int getX() const { return x; } private: int x; int y; } Client programmer can write: Point p1(10,30); Point p2; int i = p1.getX();
message receiver (this) call the method Point::getX() class of the receiver no args
A member function definition (implementation) may be included in the class definition. The compiler can insert the code for the function body where the function is called.
This is known as an inline function.
Use of inline member function is recommended
- nly for the following:
Functions whose body is very small (one or two
lines)
- Constructors
- Accessors
- Modifiers
How would you compare two points, p1 and p2. Define a method to compare their x and y coordinates.p
p1.lessThan(p2)
Overload the operator <
p1 < p2
bool Point: int::operator
- perator< (const
nst Point int& & other) er) const st { { return eturn (x < < other.x er.x) ) || ((x == == other.x er.x) ) && (y < < other. her.y)); )); }
class Point { public: Point(int i, int j) : x(i), y(j) { } Point() : x(0), y(0) { } int getX() const { return x; } bool operator<(const Point& other) const; private: int x; int y; } bool Point::operator< (const Point& other) const { return // you fill in... }
Client programmer can write: Point p1; cin>>i; cin>>j; Point p2(i,j); if (p2 < p1) then cout << “lol”;
class Point { public: // other methods as before std::ostream& operator<<( std::ostream& os, const Point& p); private: // as before }
- stream& operator<<(
- stream& os,
const Point& p) {
- s << //... you fill in
return os; }
Point p1(10,30); cout << p1;
message receiver (this) problem: The receiver is type ostream arg solution: Make this function a “friend”
class Point { public: // other methods as before friend std::ostream&
- perator<<(
std::ostream& os, const Point& p); private: // as before }
- stream& operator<<(
- stream& os,
const Point& p) {
- s << //... you fill in
return os; }
Point p1 = new Point(10,30); cout << p1;
solution: Make this function a “friend” Gives permission for this function to have complete access to the data members, even though they are private to the class
A friend is an external function or class that is given the same access to the members of a class as if it were a member. We declare the ostream insertion operator to be a friend
So it can access the data members and insert
their string representation into the output stream.
Because this operator’s left-hand operand is an
- stream object, thus it cannot be defined as a
member of the Point class.
class Point { public: // other methods as before friend std::ostream&
- perator<<(
std::ostream& os, const Point& p); private: // as before }
- stream& operator<<(
- stream& os,
const Point& p) {
- s << //... you fill in
return os; } /* how do these differ? */ Point p1 = new Point(10,30); Point p2(10,30); /* how do these differ? */ cout << p1.getX() << endl; cout << p1; /* additional examples were done in class */
class Point { public: // other methods as before bool operator==(const Point& other) const; private: // as before } bool Point::operator== (const Point& other) const { return // you fill in... }
Point p3 = new Point(10,30); if (p2 == p3) cout << “equal points” << endl;
Now that we have implemented operators == and <, what about <= ? Reuse code!
- 1. Point.h
header file (declarations & inline code)
- 2. Point.cpp
implementation file (code)
- 3. main.cpp
test driver g++ *.cpp
% g++ -c *.cpp % g++ *.o –o testPt testPt: main.o Point.o g++ main.o Point.o –o testPt main.o: main.cpp Point.h Point.o g++ -c main.cpp –o main.o Point.o: Point.h Point.cpp g++ -c Point.cpp –o Point.o clean: rm –f *.o testPoint Makefile Could type this:
- r
% make % ./testPt % make clean
For Thursday, read Chapter 2, sections 2.6 – 2.9
- f Maciel & Chapter 3, section 3.1