You are on page 1of 33

INFORMATION SYSTEMS FOR

TRANSPORTATION
Object Oriented Programming
Introduction
• Can you "assemble" a software application by picking a routine here, a routine
there, and expect the program to run? The answer is obviously no!
Unlike hardware, it is very difficult to "assemble" an application from software
components. Since the advent of computer 60 years ago, we have written tons and
tons of programs. However, for each new application, we have to re-invent the
wheels and write the program from scratch.
• The programs are made up of functions. Functions are often not reusable.
It is very difficult to copy a function from one program and reuse in another
program because the the function is likely to reference the headers, global
variables and other functions. In other words, functions are not well-encapsulated
as a self-contained reusable unit.
• In brief, the traditional procedural-languages separate the data structures and
algorithms
Procedural versus Object-Oriented Programming

• Procedural programming
It focuses on the process/actions that occur in a program.
The program starts at the beginning, does something, and ends.
• Object-Oriented programming
It is based on the data and the functions that operate on it. Objects are
instances of abstract data types that represent the data and its functions
• An object or class contains the data and the functions that operate on
that data. Objects are similar to structs but contain functions, as well.
Object-Oriented Programming (OOP)
The basic unit of OOP is a class, which encapsulates both the static attributes and dynamic
behaviors within a "box", and specifies the public interface for using these boxes.
Since the class is well-encapsulated, it is easier to reuse these classes. In other words, OOP
combines the data structures and algorithms of a software entity inside the same box.
OOP - Terminology
A Class is like a blueprint and objects are like houses built from the blueprint
• attributes: members of a class
• methods or behaviors: member
functions of a class
public interface: what is available
outside of the object. This allows
the object to provide access to some
data and functions without sharing
its internal details and design.
Class definition
• A Class is a 3-Compartment Box encapsulating Data and Functions
• In C++, we use the keyword class to define a class. There are two main
sections in the class declaration: private and public. For example:

class Circle { // Classname


private:
double radius; // Data members
string color;
public:
double getRadius(); // Member functions
double getArea();
}
Access Specifiers
Used to control access to members of the class
• public: can be accessed by functions outside of the class
• private: can only be called by or accessed by functions that are
members of the class
• protected: is inaccessible to all code outside the class, except for
code within a derived class
• NOTE: all member fields in a class are private by default (no code
outside the class can reference them), whereas fields of a struct
are public, meaning that anyone can use them.

7
Access Specifiers (continued)
• Public, private, protected can be listed in any order in a
class and can appear multiple times
• const appearing after the parentheses in a member function
declaration specifies that the function will not change any data in the
calling object. It is not mandatory.
• Making data members private provides data protection
• Data can be accessed only through public functions
• Public functions define the class’s public interface
A full example
class Circle {

private:
double radius;
string color;

public:
Circle(double r, string c) {
radius = r; color = c;
}
double getRadius() const { return radius; }
string getColor() { return color; }
double getArea() { return radius*radius*3.1416; }
};
Separating Header and Implementation
For better software engineering, it is recommended that the class
declaration and implementation be kept in 2 separate files: declaration
is a header file ".h"; while implementation in a ".cpp".

This is known as separating the public interface (header declaration)


and the implementation. Interface is defined by the designer,
implementation can be supplied by others.
While the interface is fixed, different vendors can provide different
implementations. Furthermore, only the header files are exposed to
the users, the implementation can be provided in an object file ".o" (or
in a library). The source code needs not given to the users.
The full example with separation
File circle.h File circle.cpp

class Circle { #include ”circle.h"

private: Circle::Circle(double r, string c) {


double radius; radius = r;
string color; color = c;
}
public:
Circle(double, string); double Circle::getRadius() const {
double getRadius() const; return radius;
string getColor(); }
double getArea();
}; …etc etc
Global Functions
Functions that are not part of a class, that is, do not have the
Class::name notation, are global.
This is what we have done up to this point.

In C++ procedural programming and OOP can coexist in a single


program.
Objects
• An object is an instance of a class
• Defined like structure variables:
Circle r;
• Access members using dot operator:
cout << r.getArea();
• Compiler error if you attempt to access a private member using
dot operator

13
Constructors
• Member function that is automatically called when an object is created
• Purpose is to construct an object and do initialization if necessary
• Constructor function name is class name
• Has no return type specified, because the real return type is the class

14
Default Constructors
• A default constructor is a constructor that takes no arguments.
• A simple instantiation of a class (with no arguments) calls the default
constructor:
Circle r;
• If you write a class with no constructor at all, C++ will write a default
constructor for you, one that does nothing.
• Otherwise, if and only if you want to have the default constructor, you
have to define it explicitly
Passing Arguments to Constructors
To create a constructor that takes arguments:
• indicate parameters in prototype:

Circle(double, string)

• Use parameters in the definition:

Circle(double r, string c) {
radius=r; color=c;
}
Overloading Constructors
• A class can have more than one constructor
Overloaded constructors in a class must have different parameter lists:
Circle();
Circle(double);
Circle(double, string);
• Pay attention
Circle(double r=1.0, string c="red") { radius=r; color=c; }
is a function with default arguments: it can replace the three above, but it
is not the same concept.
Example
// Construct 3 instances of the class Circle: c1, c2, and c3
Circle c1(1.2, "red"); // radius, color
Circle c2(3.4); // radius, default color
Circle c3; // default radius and color

Alternatively, you can invoke the constructor explicitly using the following syntax:
Circle c1 = Circle(1.2, "red"); // radius, color
Circle c2 = Circle(3.4); // radius, default color
Circle c3 = Circle(); // default radius and color
Classes with No Default Constructor
• When you define one or more class's constructors that require
arguments, then the class has NO default constructor
• When this is the case, you MUST pass the required arguments to the
constructor when creating an object
Note. How to define a constructor
• If we define the constructor
Point(int x = 0, int y = 0);
it works with and without arguments

• Possibility 1: member Initializer list UML class diagram


Point::Point(int x, int y) : x(x), y(y) { - Means private
//Empty or other initializations + public
} # protected

• Possibility 2: Initialization inside the body


Point::Point(int x, int y) { this->x = x; this->y
= y; }
Destructors
• Member function automatically called when an object is destroyed
• Destructor name is ~classname, e.g., ~Circle
• Has no return type; takes no arguments
• Only one destructor per class, i.e., it cannot be overloaded
• If constructor allocates dynamic memory, destructor should release it
Member Function Overloading
• Non-constructor member functions can also be overloaded:
void setCost(double);
void setCost(char *);

• Any of these functions must have a unique parameter lists as


for constructors
Getters and Setters
• To allow other to read the value of a private data member says xxx, you
shall provide a get function (or getter or accessor function) called getXxx().
A getter need not expose the data in raw format. It can process the data
and limit the view of the data others will see. Getters shall not modify the
data member.
• To allow other classes to modify the value of a private data member
says xxx, you shall provide a set function (or setter or mutator function)
called setXxx(). A setter could provide data validation (such as range
checking), and transform the raw data into the internal representation.
• With proper implementation of information hiding, the designer of a class
has full control of what the user of the class can and cannot do.
The keyword this
• You can use keyword "this" to refer to this instance inside a class definition.
"this" is actually a pointer to this object.
• One of the main usage of keyword this is to resolve ambiguity between the names of data
member and function parameter.

class Circle {
private:
double radius;
......
public:
void setRadius(double radius) { this->radius = radius; ….
Copy Assignment Operator
• The compiler also provides a default assignment operator (=), which can be used
to assign one object to another object of the same class via memberwise copy.
Circle c6(5.6, "orange"), c7;
// c6 : Radius=5.6 Area=98.5206 Color=orange
// c7: Radius=1 Area=3.1416 Color=red (default constructor)
c7 = c6;
// c7 : Radius=5.6 Area=98.5206 Color=orange

• It is also possible to use the copy constructor, that takes as argument an object
of the same class. You can define it or the compilers will create it.
Circle c7(c6); //same bahaviour as c7 = c6
Shallow and deep copies
• A shallow copy of an object copies all of the member field values. This
works well if the fields are values, but may not be what you want for fields
that point to dynamically allocated memory. The pointer will be copied,
but the memory it points to will not be copied -- the field in both the
original object and the copy will then point to the same dynamically
allocated memory, which is not usually what you want. The default copy
constructor and assignment operator make shallow copies.
• A deep copy copies all fields, and makes copies of dynamically allocated
memory pointed to by the fields. To make a deep copy, you must write a
copy constructor and overload the assignment operator, otherwise the
copy will point to the original, with disasterous consequences.
Remark
• If the object has no pointers to dynamically allocated memory, a shallow copy is
probably sufficient. Therefore the default copy constructor, default assignment
operator, and default destructor are ok and you don't need to write your own.
• Otherwise you should include a user-defined copy constructor (or operator = )
and a destructor
• If you don't write a destructor, your code will probably still work, but it may have
storage leaks (some uses of the new operator will have no corresponding use
of delete).
• For details
http://pages.cs.wisc.edu/~hasti/cs368/CppTutorial/NOTES/CLASSES-PTRS.html
Exercise
Implement the following class

class Rectangle
{
private:
double width;
double height;
public:
Rectangle();
Rectangle(double, double);
void setWidth(double);
void setHeight(double);
double getWidth() const;
double getHeight() const;
double getArea();
bool isEqual(Rectangle);
};
Solution
Rectangle::Rectangle() { width = height = 0.0; }

Rectangle::Rectangle(double w, double h) { width = w; height = h; }

void Rectangle::setWidth(double w) { width = w; }


int main(int argc, const char * argv[]) {
void Rectangle::setHeight(double h) { height = h; } Rectangle r1(5,4);
Rectangle r2(4,5);
double Rectangle::getWidth() const { return width; } Rectangle r3;
r3 = Rectangle(1,2);
double Rectangle::getHeight() const { return height; } cout << "R1: " << r1.getArea() << endl;
cout << "Are R1 and R2 equal? " << boolalpha <<
double Rectangle::getArea() { return width*height; } r1.isEqual(r2) <<endl;
cout << "Are R1 and R3 equal? " << r1.isEqual(r3) << endl;
bool Rectangle::isEqual(Rectangle r) { return 0;
return (this->getArea() == r.getArea()); }
}
Using Private Member Functions
• A private member function can only be called by another member
function
• It is used for internal processing by the class, not for use outside of
the class
• If you wrote a class that had a public sort function and needed a
function to swap two elements, you’d make that private
Arrays of Objects
• Objects can be the elements of an array: Rectangle rooms[8]
• Objects in an array are referenced using subscripts
• Member functions are referenced using dot notation:
rArray[1].setWidth(11.3);
cout << rArray[1].getArea();
• Default constructor for object is used when array is defined. Otherwise
you must use initializer list to invoke constructor with arguments:
Rectangle rArray[3]={Rectangle(2.1,3.2), Rectangle(4.1,
9.9), Rectangle(11.2, 31.4)};
Pointers to Objects
• Can define a pointer to an object:
Rectangle *rPtr;
rPtr = &otherRectangle;
• You can dynamically allocate Objects
rPtr = new Rectangle();
• Can access public members via pointer:
rPtr->setLength(12.5);
cout << rPtr->getLength() << endl;
• When the object is destroyed, its destructor executes:
delete rPtr;
Exercize
• Make class Point with a constructor
Point( float xcoordinate, float ycoordinate );
• Write the following methods:
distance_to_origin returns a float.
printout uses cout to display the point coordinates.
distance computes the distance between this point and another:
if A,C are Point objects, c = A.distance(B) computes the distance.

You might also like