CS 132 Spring 2008 Chapter 2 Object-Oriented Design (OOD) and C++ Ideas: * Inheritance (and...

Post on 18-Jan-2016

216 views 0 download

Tags:

Transcript of CS 132 Spring 2008 Chapter 2 Object-Oriented Design (OOD) and C++ Ideas: * Inheritance (and...

CS 132 Spring 2008Chapter 2

Object-Oriented Design

(OOD) and C++

Ideas: * Inheritance (and protected members of a class)

** Operator overloading

Pointer this

* Operator overloading with friends

** Templates

Three Basic Principles of OOD

Encapsulation– combining data and operations into a single unit– where have we done this?

Inheritance– ability to create new data types from existing ones

Polymorphism– using the same expression to denote different

meanings, e.g., overloading, overriding– where have we done this?

Inheritance

person

student faculty USresident

Derive student from person:

public members (e.g. setName) in person can be used in student

student has additional members (gpa in private, setGPA in public)

Multiple inheritance (we won't cover): faculty and USresident

person → student

class personType

{

public:

void print() const;

void setName(string first, string

last);

void getName(string& first,

string& last);

personType(string first = "",

string last = "");

private:

string firstName;

string lastName;

};

class studentType: public personType

{

public:

void setStudent(string first,

string last,

int gpa);

void setGPA(int gpa);

float getGPA();

studentType(string first = "",

string last = "",

int gpa = 0);

private:

int GPA;

};

public members of personType are public in studentType:

studentType student;student.setName("Fred", "Fink") //works

person → student

class personType

{

public:

void print() const;

void setName(string first, string

last);

void getName(string& first,

string& last);

personType(string first = "",

string last = "");

private:

string firstName;

string lastName;

};

class studentType: private personType

{

public:

void setStudent(string first,

string last,

int gpa);

void setGPA(int gpa);

float getGPA();

studentType(string first = "",

string last = "",

int gpa = 0);

private:

int GPA;

};

public members of personType are not public in studentType:

studentType student;student.setName("Fred", "Fink") //does not work

different

Protected Members of a Class

Problem: members of studentType cannot access firstName and lastName because they are private in personType

If derived class needs access to members of the base class

the members of base class are “protected”

E.g. change "private" to "protected" in the parent class

person → student

class personType

{ public:

void print() const;

void setName(string first, string

last);

void getName(string& first,

string& last);

personType(string first = "",

string last = "");

protected:

string firstName;

string lastName;

};

class studentType: public personType

{ public:

void setStudent(string first,

string last,

int gpa);

void setGPA(int gpa);

float getGPA();

studentType(string first = "",

string last = "",

int gpa = 0);

private:

int GPA;

};

private members of personType can be used in studentType implementation

See person2.h

different

Inheritance In person.h:public:

void print() const;

In student.hclass studentType: public personType

//public members of person can be used in derived class instances

e.g. studentType aStudent;

aStudent.print();

In student.hclass studentType: private personType

//person public members can be used only to implement derived class

//but not on objects of that type

e.g. studentType aStudent;

aStudent.print(); //NOT ALLOWED

Rarely used

Example: a derived class patientType where you don't want to reveal patient namespersonp.h

Inheritance In person.h:protected:

string firstName; //visible to derived classes

string lastName; //visible to derived classes

private:

string firstName; //not visible to anyone except personTypeImp

Redefining Base Class Members

print() defined in personType does not print the GPA

Definition in studentType overrides print in personType

studentTypeImp.cpp illustrates

– redefinition

– accessing protected members of personType

(allowed because they are protected)

– using the inherited function for print in studentType

Pitfall:

– constructors must be redefined

Inheritance Summary

Public members of the base class– inherited by the derived class– can be directly accessed anyone

Private members of base class– private to base class – cannot be directly accessed by anyone

Protected members of base class– can be directly accessed only by derived class

Derived class can redefine member functions of base class– redefined function must have the same name and parameters– redefinition applies only to objects of the derived class– if the same name is used with different parameters, it is different

Preprocessor Commands (p. 78)

//Header file person.h

#ifndef H_person#define H_person ... the contents of personType.h#endif

#ifndef H_person means “if not defined H_person”#define H_person means “define H_person”#endif means “end if”

This prevents compiling a file twiceNot required in Visual C++

See person2c.h

Composition (p. 80)

Another (easier) way to relate two classesA member of a class in an object of another class typeAnalogous to records having other records as components

– e.g. a person has a birthday– “has-a” relation between classes

E.g.:

class personalInfoType{... private: personType person; dateType bDay; int personID;};

Confusing section: Pointer this

Pointer: – a variable that contains an address of another variable– when you declare a variable, its name and type is stored in a

symbol table along with a pointer to the address of the variable– later: pointer types that will be an important way to implement

dynamic data structures

Every object of a class maintains a (hidden) pointer to itself called “this” (a reserved word)

When the object invokes a member function, the member function references the pointer "this" of the object

Pointer this

Example on p. 90 (personImp.cpp):

// & means the object using the method is by reference// *this is the object that is modified

personType& personType::setFirstName(string first){

firstName = first;return *this;

}

Better (personImpv.cpp):

//the method operates directly on the objectvoid personType::setFirstName(string first){

firstName = first;}

Both are called via aPerson.setFirstName("Fred");

Polymorphism: Operator Overloading

Recall how clumsy printing and addition are for complexType:num1.print();

num3 = num1.add(num2);

Nicer: cout << num1;

num3 = num1 + num2;

Operator function: overloads an operator

Syntax of the heading of an operator function:returnType operator operatorSymbol (arguments)

e.g.

complexType operator+(const complexType& otherComplex) const;

See example files

Overloading +

In driver (testComplex.cpp):num3 = num1.add(num2); // add is applied to object num1 with parameter num2

num3 = num1 + num2; // + is applied to object num1 with parameter num2

In complexType.h:complexType add(const complexType& otherComplex) const;

complexType operator+(const complexType& otherComplex) const;

Implementation in complexType.cpp (both the same!):complexType temp;

temp.realPart = realPart + otherComplex.realPart;

temp.imaginaryPart = imaginaryPart +

oherComplex.imaginaryPart;

return temp;

Overloading the Stream Insertion Operator (<<)

Let's try this with: cout << aComplex

object operator parameter

But cout is ostream, not personType

We need a friend: – a nonmember function with access to private data members

To make function a friend to a class, reserved word friend precedes prototype

friend appears only in prototype, not in the function definition

Overloading <<

Function prototype (included in the class):friend ostream& operator<<(ostream&, const complexType&);

Function definition:ostream& operator<<(ostream& osObject, const complexType& complex){ osObject<<complex.realPart; osObject<<" + "; osObject<<complex.imaginaryPart; osObject<<"i"; return osObject; //pointer this format}

text example displays data in (a,b) format. How would this differ?osObject<< "(" << complex.realPart << ", " << complex.imaginaryPart << ")";

Overloading >> in (a,b) format

Earlier program: user entered a and b separately.

What if the number is in (a,b) format?

a. Read and discard left parenthesis (

b. Read and store the real part a

c. Read and discard the comma ,

d. Read and store the imaginary part b

e. Read and discard the right parenthesis )

Overloading >>

Function Prototype (included in the definition of the class):friend istream& operator>>(istream&, className&);

Function Definition:istream& operator>>(istream& isObject, complexType& object){

char ch;

isObject>>ch; isObject>>complex.realPart; isObject>>ch; isObject>>complex.imaginaryPart; isObject>>ch;

return isObject;

} no const since the object will change

Bad News

Example programs do not compile

1. Change #include <iostream> to #include <iostream.h>

2. Remove using namespace std

Why? A peculiarity of Visual C++

Overloading Unary Operators

Unary operators: one argument

E.g. a++ (unary) versus a + b (binary)

The second argument was a parameter in the overloaded definition

complexType operator+(const complexType& otherComplex) const;

cComplex = aComplex + bComplex

the object the parameter

But there is no second argument:

dateType operator++(); //get the next day

aDate++;

the object

the operator

Templates

Powerful C++ tools

Use a function template to write a single code segment for a set of related functions that may operate on different types (E.G. max, last semester)

Use a class template for classes that may have similar functionality on different data types

Example:

– listType

– we will use this in the next program to review arrays

Syntax

Syntax for a function template:template<class Type> //Type is the parameter

function definition;

Syntax for a class template:template<class Type>

class declaration

New rule– the class header and implementation must be compiled together

Options– put them both in the same file (what we will do)

– put an include for the .cpp at the end of the header