Transcript Slide 1

COIT12140
Object-Oriented
Programming
Week 5 .. Putting it all together
General Plan
• Identify the object to be modelled
• Identify the relevant data or attributes of this
object
• Add member functions
– House keeping functions
– Functions specific to the class
• Start with a minimal set of member functions
• Add extra functions as required
Putting Classes Together
• A general plan for implementing classes
– Classes not using dynamic memory
allocation
– Classes uses dynamic memory
– Array classes
• Property class – A class using dynamic
memory
• Day class– A class for an enumerated variable
• Properties class – An array class for objects
Classes not Using Dynamic memory
ClassName
-data members
+constructor(s)
+destructor
+ << operator
+ >> operator
+ accesor functions
+mutator functions
Constructor guarantees a valid
object
>> and << allow easy input
and output
Default copy constructor &
assignment operators are OK
Classes using Dynamic Memory
ClassName
-data members
+constructor(s)
+copy constructor
+destructor
+ overloaded =()
+ << operator
+ >> operator
+ accesor functions
+mutator functions
Default copy constructor,
destructor and
assignment operators
are unsatisfactory
Array Classes
• C++ doesn’t check array subscripts
– You can access the 11th item in a 10 item array
• Writing array classes enables array subscripts
to be checked – overload subscript[]()
operator
• Overloading =() allows arrays to be equated
• Overloading >> and << allows easy input of
arrays
• Dynamic memory can be used to create the
correct size of array
Property
- owner: char* = 0
UML Class diagram Property class
- address: char* = 0
UML diagram
for Property
class
- tenant: char* = 0
- rent: float = 0.0
+ Property()
+ Property
(char*,char*,char*,float)
+ Property(const Property &)
•Character
strings set to
NULL (0)
•3 constructors
Property
+ ~Property
+ assignment operator =()
UML diagram
for Property
Class .. 2
+ << operator
UML Class diagram for Property class (cont)
+ >> operator
+ comparison operator ==
+ accessor functions
+ mutator functions
+ ….
class Property
property.h
{
// friend functions
property.h ..1/4
// display property details to the screen
friend ostream& operator<< (ostream& out,
const Property& aProperty);
// ..
// inputs the details of a property from file
friend ifstream& operator>> (ifstream & in,
Property& aProperty);
// member functions
property.h .. 2
public:
Property.h .. 2
Property();
// Default Ctor
Property(const char* own, const char* add,
const char* ten, float rnt);
// param Ctor
Property(const Property& aProperty);
~Property();
// copy Ctor
// destructor
// overloaded assignment operator
Property& operator= (const Property& aProperty);
// compare 2 properties
property.h .. 3
bool operator==( const Property & ) const;
Property.h .. 3/4
// Determine if two Property objects are not equal and
bool operator!=( const Property &right ) const
{ return ! ( *this == right ); }
// Accessor functions
const char* getAddress() const;
// return the address
float getRent() const;
// return weekly rent
// member data
property.h .. 4
Property.h .. 4/4
private:
char* owner ;
// owner's name
char* address; // property address - a single string
char* tenant;
float rent;
};
// tenant's name
// the weekly rental
about the header file
• The header file resembles the UML
representation of the Property class
• The order of contents
– Friend functions
– Publicly accessible members
– Lastly private members
• The layout of this header file can be used as a
pattern for other classes
• The !=() function is declared in-line
// default Property constructor
// sets the string pointers to null and rent to zero
Default Ctor
Property::Property()
{
owner = 0;
address = 0;
tenant = 0;
rent = 0.0;
}
// or owner = NULL;
// default Property constructor
// sets the string pointers to null and rent to zero
Default Ctor – using an initialisation list
Property::Property() : owner (0), address (0),
tenant (0), rent (0.0)
{}
// parameterized Property constructor
// allocates space for the char strings,
// sets them to the specified values and sets the rent
Property::Property(const char* own, const char* add,
const char* ten, float rnt)
{
owner = new char[strlen(own)+1]; // space for name
assert(owner!=0);
// check allocation
strcpy(owner,own);
// copy the name
// …..
rent = rnt;
}
Parameterized Ctor
// copy constructor ... has to allocate space
Property::Property(const Property& aProperty)
{
// space for owner's name
Copy Ctor
owner = new char[strlen(aProperty.owner) + 1];
assert(owner!=0);
// check allocation
strcpy(owner,aProperty.owner); // copy name
// …..
rent = aProperty.rent;
}
// destructor
Property::~Property()
Dtor
{
if(owner !=0)
delete [] owner;
owner = 0;
// …
}
// return memory
// set the pointer to null
// overloaded assignment operator
Property& Property::operator=( const Property& aProperty)
Assignment operator
{
if(&aProperty != this)
// guard against self assignment
{
delete [] owner;
// recover memory
// space for owner
owner = new char[strlen(aProperty.owner) + 1];
assert(owner!=0);
// check allocation
strcpy(owner,aProperty.owner);
// copy the string
Assignment operator ..2
// overloaded assignment operator .. 2
// ….
rent = aProperty.rent;
}
return *this;
}
// Overloaded output
Overloaded output operator
ostream& operator<< (ostream& out,
const Property& aProperty)
{
out << aProperty.owner <<endl << aProperty.address ;
out << aProperty.tenant << endl << aProperty.rent ;
out << endl <<endl;
return out;
}
// enable chaining
// friend function to input a property from the keyboard
istream& operator>> (istream& in, Property& aProperty)
Overloaded input
{
char strbuf[MAXSTRING];
// temp buffer for input
cout << " Enter the property details " << endl;
delete [] aProperty.owner;
// recover memory
cout << " Enter the property's owner ";
cin.getline(strbuf,MAXSTRING,'\n');
// could goof proof
aProperty.owner = new char[strlen(strbuf) +1]; // allocate memory
assert(aProperty.owner != 0);
strcpy(aProperty.owner,strbuf);
// check memory allocation
// copy the string
// friend function for input .. 2
cout << " Enter the property's rent " ;
cin >> aProperty.rent;
Overloaded input .. 2
// could goof-proof input
while (aProperty.rent < 0.0)
{
cout << "Invalid rent .. retry ";
cin >> aProperty.rent;
}
cin.ignore(MAXSTRING,'\n');
// remove any trailing chars
// from input stream
return in;
}
Properties
UML class diagram for Properties - an array class
- ptr: Property* = 0
Array class
- propertyCount: int = 0
+ Properties(int =10)
+ Properties(const Properties &)
+~Properties
+assignment operator =()
Class uses
dynamic
memory
Properties
UML class diagram for Properties class .. 2
Array class
+ << operator()
+ >> operator()
+ subscript operator[](): Property&
Two
+ subscript operator[]()const:
subscript
const Property& operators
+fileInputProperties(char*)
+deleteProperty(int)
// constructor .. size defaults to 10
Properties::Properties(int arraySize)
Constructor
{
propertyCount = ( arraySize > 0 ? arraySize : 10 );
ptr = new Property[propertyCount]; // space
assert( ptr != 0 );
}
// copy constructor ... also has to allocate space
Properties::Properties(const Properties& props)
Copy Ctor
{
propertyCount = props.propertyCount;
ptr = new Property[propertyCount];
assert( ptr!= 0);
// copy over the property details one at a time
for (int i =0; i < propertyCount; i++)
ptr[i] = props.ptr[i];
}
// lvalue & rvalue are Property objs
// overloaded assignment operator
Properties& Properties::operator=( const Properties& props)
Assignment operator .. 1
// if the arrays are of different size, delete the old array
// and make space for the new one
if(propertyCount != props.propertyCount)
Hey, where’ the
{
if(&props != this) statement
delete [] ptr;
Leaving it out will cause problems!!
propertyCount = props.propertyCount;
ptr = new Property[propertyCount];
assert( ptr!= 0);
// subscript operator .. returns a Property
Subscript operator
Property& Properties::operator[]( int subscript)
{
// check for subscript out of range error
assert( 0 <= subscript &&
subscript < propertyCount );
return ptr[ subscript ];
}
// reference return
// delete a property and shuffle the array
void Properties::deleteProperty(int subscript)
Delete a property
{
// move all Property objects after deleted up one place
for (int i = subscript ; i < propertyCount-1; i++)
ptr[i] = ptr[i+1];
// reduce the number of properties
propertyCount--;
}
enum class
• enum EnumDay {mon, tue, wed, thu,
fri, sat, sun, MAX_DAYS};
• enum types are often implemented
as classes
– Arithmetic operations
– Overloaded input & output
UML Class diagram
Day
-eDay:EnumDay
+ Day(string )
+ << operator
+ >> operator
+ operator ++()
+ operator ++(int)
Class is Day
Data member is eDay
Enumerated type is
EnumDay
Meaningful operations
++fri is sat
++sun is mon
sat + sun = ?
cin >> aDay
// Header file for the enumerated type
// Global definition of enumerated type
Day .h
enum EnumDay {mon, tue, wed, thu, fri,
sat, sun, MAX_DAYS};
class Day
{
// functions to input and output a day
friend istream& operator >> (istream& in,
Day& aDay);
friend ostream& operator <<(ostream& out,
const Day& aDay);
Day.h
public:
Day(const string = "Sunday"); // Ctor
Day&
operator++();
// prefix
const Day operator++(int); //
postfix
private:
EnumDay eDay;
};
Overloaded input
istream& operator>>(istream& in,Day& aDay)
{
string inputString, d;
in >> inputString;
// Test the first 3 characters
d = lowerCase(inputString.substr( 0, 3));
if (d == "mon")
aDay.eDay = mon;
else if (d == "tue")
aDay.eDay = tue;
// ..
else
cout << "Invalid day value";
return in;
}
ostream& operator << (ostream& out,
const Day& aDay)
{
switch(aDay.eDay)
{
case mon: out << "Monday";
break;
case tue: out << "Tuesday";
break;
// ..
}
return out;
}
Overloaded output
Prefix increment
// prefix increment
Day& Day::operator ++()
{
int i = static_cast<int>(eDay);
i = ++i % MAX_DAYS;
eDay = static_cast<EnumDay>(i);
return *this;
}
Postfix Increment
// postfix increment
const Day Day::operator ++(int)
{
Day oldDay;
oldDay = *this;
++(*this);
return oldDay;
}