CS 132 Spring 2008 Chapter 2 Object-Oriented Design (OOD) and C++ Ideas: * Inheritance (and...
-
Upload
ginger-mason -
Category
Documents
-
view
216 -
download
0
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