Chapter 13. Procedural programming vs OOP Procedural programming focuses on accomplishing tasks...

41
Chapter 13

Transcript of Chapter 13. Procedural programming vs OOP Procedural programming focuses on accomplishing tasks...

Chapter 13

Procedural programming vs OOP Procedural programming focuses on

accomplishing tasks (“verbs” are important).

Object-oriented programming focuses on objects (“nouns” are important).

What is an object? A software entity that contains both data and procedures.

Separation of Data and Code

In procedural programming, data and code are two separate entities. This can cause problems such as:

If the underlying data structures change, all code that uses the data must be rewritten.

Users of the data must be familiar with its internal structure.

Encapsulation

Encapsulation refers to the combining of data and code into a single object.

Only the designer of the class must know its workings. And, if the data structures change, the INTERFACE remains the same.

A Simple Example – Rectangle class Rectangle

{

private:

double width;

double length;

public:

void setWidth(double);

void setLength(double);

double getWidth() const;

double getLength() const;

double getArea() const;

};

Data Hiding

An object can hide its data from the code that is outside of the object (i.e. “private”).

In this way: Users of an object can interface with the

object in the same way, regardless of internal changes that may occur.

Users of the object cannot erroneously change the data.

Object Reusability

As long as the user understands an object’s interface, it is easy to use an object that has been created by another programmer.

Example: consider the string class. You do not know its internal representation, yet it is fairly simple to use.

Defining Member Functions

void Rectangle::setWidth(double w) { width = w; }Use the scope resolution operator :: which

says that setWidth is a member of the Rectangle class.

[see program 13-1 in text.]

Defining an Object

Rectangle box;

box is called an instance of the Rectangle class.

To call a member function of an object, use the DOT operator:

box.setWidth(12.7);

[see program 13-2]

Accessors and Mutators

Accessors, or “getter functions” are functions that get a value of a member variable. They do not change anything in the object, and therefore should be defined as const functions.

Mutators or “setter functions” change one or more member variables.

Pointers to objects

Pointers to class objects work exactly the same way as pointers to struct objects.

Example:Rectangle *recptr;Rectangle box;recptr = &box;recptr->setWidth(12.5);recptr->setLength(4.8);recptr = new Rectangle;

Private Members and Data Validationvoid Rectangle::setWidth(double w){ if (w >=0) width=w; else { cout << “invalid data”; exit(1); }}

Separating Class Specification and Implementation

The user of a class does not have to see the actual code of the member functions.

The user needs 2 things:

1. compiler must see the class declaration

2. linker must have the actual code to generate the executable.

Recall: Program Translation

Compiler: high level language -> object code

gcc –c myhmwk.cpp

Linker: object code -> executable code

Header files

A header file includes the class declaration.

For example, for the Rectangle class, we’d create a file called: Rectangle.h

All programs that use the Rectangle class will:

#include “Rectangle.h”

Class Implementation

The actual code (i.e. function definitions) of a class will reside in a .cpp file.

For example, Rectangle.cpp will hold definitions of all Rectangle member functions.

All programs that use the Rectangle class will link with the object code of Rectangle.cpp

Linking Several Files

Example: suppose you wrote a program called shapes.cpp that used objects of type Rectangle and Circle.

To compile your program, you type:

g++ -c shapes.cpp

To link, you type:

g++ shapes.o Rectangle.o Circle.o

More on Header Files

To avoid multiple declarations of the same class, always “wrap” your header file with:

#ifndef RECTANGLE_H

#define RECTANGLE_H

….. (contents of header file)

#endif

Rectangle.h Circle.h

#include “shapes.h” #include “shapes.h”

#include “Rectangle.h”#include “Circle.h”

mainprogram.cpp

Advantages of Separate Compilation Great for Reusability

Protects code

Maintenance made easy – only need to recompile those files that were changed, and then link object code.

Makefiles and Project Files

In UNIX, you can automate the process of separate compilation using a “makefile” and the “make” utility.

In Windows, you create a project file.

The next step of your homework assignment will be to move to classes and to separate compilation.

13.6 Inline member functionsShort functions can be written in the

declaration of the class (.h file).

class Rectangle{ private:

double width;

double length;

public:

double getWidth() const { return width; }

};

Inline member functions (cont.)

Do not need a scope resolution operator :: since this is inside the class.

This is actually a directive to the compiler to replace every call with the actual code (similar to a macro).

Improves efficiency since function calls are eliminated.

Long functions should never be placed inline, since this will blow up the size of the program.

ConstructorsA constructor is a function that is

automatically called when an object is created (i.e. defined).

The name of the constructor is the same as the class name.

For example:class Rectangle{…..public: Rectangle();}[see program 13-5 in text.]

Code for Constructor

Rectangle::Rectangle()

{ width=0.0;

length=0.0; }

No return type Yes, may accept arguments. Use the constructor to initialize the

object’s member variables.

“Calling” the constructor

When you instantiate an object, the constructor automatically gets called.

For example:

Rectangle box;

box’s width and length member variables have been set to 0.0 by the constructor.

The purpose of the constructor is to initialize data members of an object before the members are used.

Default Constructor

A constructor without arguments is called the default constructor. It gets called automatically, when an object is instantiated.

NOTE: you do not have to put () for a default constructor to be called.

If the class does not include a constructor, the compiler creates a default constructor that does nothing.

Constructors and “New”

The constructor IS called when dynamically allocated objects are created.

Example:Rectangle *recptr; // define a pointer

recptr = new Rectangle; // default constructor is called here.

Constructors with ArgumentsExample:

Rectangle::Rectangle(double w, double h)

{

width=w;

length=h;

}

In main:Rectangle box(10.0, 20.0);

int w=9, len=9;

Rectangle box2(w, len);

Overloading Constructors

You may include as many constructors as you wish, as long as the parameter list is different.

Recall: this is the same as overloading any function.

Recall: with strings, we are familiar with several different constructors.

string str;

string str(“Hello”);

string str(str2);

….

Default Arguments

A default argument to a function is an argument that does not have to be sent when the function is called. If no argument is passed to the function, a default value is assigned to the parameter.

Example:

int displayChar(char c=‘?’) {

cout << c << endl;

}

Default args in a constructor

Instead of defining a default constructor, and a constructor with arguments, you can use default arguments in the constructor.

NOTE: this is considered a default constructor since it can be called without arguments. Therefore, you cannot define another default constructor.

Example of default argumentsRectangle::Rectangle(double w=0.0, double len=0.0)

{

width=w;

length=len;

}

Note: If there is no default constructor, then you cannot create an object without sending the necessary arguments.

Destructors

Similar to constructors, in that a destructor is automatically called when an object goes out of scope, or it is deleted.

Same name as the class, preceded by ~ Usually used to free up memory that

was dynamically allocated.

Destructor Example

Rectangle::~Rectangle()

{

cout << “this object is about to be destroyed.”;

} No return type No arguments (hence there can be only

1 destructor.)

Inventory Example

See programs 13-11 and 13-12 in the text.

Private Member Functions

Note the function createDescription in the InventoryItem class is private.

Why create a private member function?

Used for functions that help the class internally accomplish tasks that should never be done by a user.

Arrays of Objects

Example:

InventoryItem inventory[100];

Use the DOT operator as we did with structures:

inventory[i].setUnits(30);

Question: When does the constructor get called?

When you define the array, the constructor is called 100 times, once per object.

Arrays cont.

Which constructor is called?

The default constructor. You can add an initializer, and then other

constructors will be invoked.

Example:

InventoryItem inventory[1]={“Hammer”, “Wrench”, “Pliers”};

If values are missing, the default constructor will be called (similar to all zeros for remaining array).

Arrays cont.

What about >1 argument? Use form of a function call.

Example:

InventoryItem inventory[1]={“Hammer”, InventoryItem(“Wrench”, 8.75, 20)};

Here we are explicitly invoking the constructor.

Lab 4

Posted on course website.