Upload
lewis-mark-cain
View
241
Download
0
Tags:
Embed Size (px)
Citation preview
Abstract Data Types Using Classes
Lecture-5
Abstract Data Types Using Classes
Representing abstract data types using C++
We need the following C++ keywords class keyword to define a class (ADT) private keyword to define 'hidden' parts of the
class public keyword to define the visible interface of
the class The scope resolution operator (::) used to link
together classes and methods
The Anatomy of a class
A Class has two parts (just like an ADT) A private (hidden) part A public interface
The public part defines the behavior of the object (methods)
The private part contains the data It is normal practice to put attributes in
the private part of the class where they can only be accessed by methods
The Anatomy of a class
It is possible to put attributes (data) in the public part of the class but this undermines encapsulation.
It is also possible to put methods in the private part of a class but these may not be used as an external interface (however they may be used by other methods)
The Unified Modelling Language method of drawing class diagrams
The first element of the class diagram is the Class name this is the unique name of the Object for the class.
Class Name
Attributes:
Methods()
Attributes When drawing attributes the following
syntax is used.
The scope section of the attribute syntax is used to indicate the visibility of the attribute.
[scope] [attribute name] : [data type]
scope symbol meaning-------------------------------------------
- Private+ Public# Protected
(no symbol) Implementation
Attributes
When drawing attributes the following syntax is used.
The attribute name is a unique name for the attribute, and finally the data type represents what type is used for the attribute.
For example the following attribute definition represents a private integer called AccountNumber.
[scope] [attribute name] : [data type]
- AccountNumber : int
Methods
When drawing methods the following syntax is used.
As with attributes the scope symbols are used to indicate the visibility
Next comes the method name. Within the ( ) of the method an optional list of
parameters to the method may be placed. These are comma separated and use the following
layout.
Finally the return type of the method (if any) is written.
scope] [Method name]([optparameters],): [return type]
(ParameterName :int, Parameter2 : char)
Methods
For the following example a method called setAccountNum is prototyped, it is passed one integer value an returns a boolean argument.
+ setAccountNum(AccNumIn :int) : bool
Finally the return type of the method (if any) is written.
Single File Instruction header files define interfaces for functions, structures,
unions and classes
They may also define variables, however if this header file is then included in more than one module the linker will complain as the same variable is defined twice.
To overcome this problem we can use Single File Inclusion
The traditional way of doing this is as follows Use the name of the Header file as an identifier for the
pre-processor and create a unique #define name place a #include directive in the code to define the
module name If the #define does not exist then it will be included if
it does there is no need to include it again.
A Class Example
#ifndef __ExampleClass_H_#define __ExampleClass_H_class ExampleClass{
private : int i;
public: void SetValue(int value_in)
{ i=value_in
} int GetValue() { return i; }}; //end of class#endif
Some observations on the class A class definition is terminated with a semicolon (unlike
a function definition)
The members of a class are private by default, so the private keyword could be omitted. The integer variable 'i' is private and therefore inaccessible from outside the class, except indirectly via the setValue and getValue methods
Methods are usually know as 'member functions' in C++. The member functions 'setValue' and 'getValue' are defined 'inline' (inside the class definition).
setValue is of void type because it doesn't return a value
getValue returns and int (the value of i)
More on declaring Methods
In the previous example the methods are declared 'inline' i.e. as part of the class
This is a bad idea as the code is duplicated for every object created which
takes up memory
and leads to inefficient coding
Most modern compilers will only allow 'inline' functions of about two lines of code or less
So What do we do to overcome this limitation ?
The Scope Resolution Operator (::)
#ifndef __ExampleClass_H_#define __ExampleClass_H_class ExampleClass{
private :int i;
public: void SetValue(int v_in) int GetValue()}; //end of class#endif
#include “ExampleClass.h”void ExampleClass::SetValue(int v_in)
{ i=v_in
}
int ExampleClass::GetValue() { return i; }
ExampleClass.h ExampleClass.cpp
More on Scope Resolution In the above example the methods are declared as part
of the class
however there is no code defined in the class
The methods are then prototyped after the class definition using the following
return_type Class_name::method_name(parameterlist)
This has the effect that only one version of the method exists at run-time This method is available to all instances of objects of
this class
Thus saving memory and improving efficiency
A more Complex Example The previous example was a bit simple, so here is a more
complex one A 2D Point object has two attributes: x and y ( the x value of
the point the y value of the point) And the following methods
get x value get y value
Modifier Methods set x value set y value move left move right move up move down
Complex Example: Class Diagram We can now generate a class diagram
Point2D
- x : float .......- x : float
+ SetX(Xin : float)+ SetY(Yin : float)+ GetX() : float+ GetY() : float+ Left() + Right()+ Up()+ Down()
Code#ifndef __POINT2D_H__ #define __POINT2D_H__class Point2D{ private : float x; float y; public : void SetX(float Xin); void SetY(float Yin); float GetX(void); float GetY(void); void Up(void); void Down(void); void Left(void); void Right(void);};#endif
Point2D.h
Code#include”Pont2D.h”void Point2D::SetX(float Xin){ x = Xin; }void Point2D::SetY(float Yin){ y = Yin }float Point2D::GetX(void){ return x; }float Point2D::GetY(void){ return y; } void Point2D::Up(void) { y = y+1.0; }void Point2D::Down(void){ y = y-1.0; }void Point2D::Left(void){ x = x+1.0; }void Point2D::Right(void){ x = x-1.0; }
Point2D.cpp
#include <iostream>using namespace std;#include "Point2D.h"
int main(void){Point2D Pt;
point.SetX(1.0);point.SetY(2.0);cout <<"Point value is ["<<Pt.GetX()<<","<<Pt.GetY()<<"]"<<endl;point.Up();point.Left();cout <<"Point value is ["<<Pt.GetX()<<","<<Pt.GetY()<<"]"<<endl;point.Right();point.Down();cout <<"Point value is ["<<Pt.GetX()<<","<<Pt.GetY()<<"]"<<endl;return 0;}
Point2DTest.cpp
Makefiles We are using different files, we need to use makefile
as follows OBJECTS=Point2D.o PointTest.o
PointTest : $(OBJECTS)g++ -Wall -g $(OBJECTS) -o PointTest
Point2D.o : Point2D.cpp Point2D.hg++ -Wall -g -c Point2D.cpp
PointTest.o : PointTest.cpp Point2D.hg++ -Wall -g -c PointTest.cpp