Date post: | 15-Jan-2016 |
Category: |
Documents |
Upload: | sandra-keal |
View: | 212 times |
Download: | 0 times |
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Week 6
• Lab 2 is marked
• Hand in Lab 3
• Questions from Last Week
• Operator Overloading
• Lab 4
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Date Week Topic ChapterHand Out Due Back Test
6-Jan-03 1Administrivia / Overview / Intro to C++ / Control Structures 1
13-Jan-03 2 Functions / Arrays, Pointers, Strings 2,3,4,5Lab 1 / Lab 2
20-Jan-03 3 Classes, Data Abstraction 6 Lab 1 5%27-Jan-03 4 More on Classes 7 Lab 3 Lab 2 5%3-Feb-03 5 No Lecture
10-Feb-03 6 Operator Overloading 8 Lab 4 Lab 3 5%17-Feb-03 Reading Break24-Feb-03 7 Inheritance 9 Lab 4 5% Midterm 25%3-Mar-03 8 Virtual Functions and Polymorphism 10 Lab 5
10-Mar-03 9 Stream IO 11 Lab 6 Lab 5 5%17-Mar-03 10 Templates 12,13 Lab 7 Lab 6 5%24-Mar-03 11 Exceptions31-Mar-03 12 File IO 14 Lab 7 5%
??? Exam Final 40%
Schedule
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Stack vs. Heap
• Allocate on the stack:
if (x > 0)
{
Rectangle r(3,4);
cout << r.area();
}• Object exists only while execution is between the
brace brackets
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Stack vs. Heap
• Allocate on the heap:if (x > 0){ Rectangle* pr = new Rectangle(3,4); cout << pr->area();}
• Object continues to exist until it is deleted• If you plan to save a pointer and use it elsewhere,
it must point to a location on the heap
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Gets and Sets
class BankAccount{private: int balance; //in penniespublic: int getbalance() {return balance;} void setbalance(int bal) {balance = bal;}// other stuff};
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Encapsulation to the Rescueclass BankAccount{private: float dollarbalance; //in dollarspublic: int getbalance() {return (int) (dollarbalance*100);} void setbalance(int bal) {dollarbalance = bal/100.0;}// other stuff};
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Overloading Revisited
• When a two functions have the same name, they are overloaded
class foo
{
public:
int something(int x);
int something();
};
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Operator Overloading
• All languages have operator overloading
int x = 1 + 1;
float f = 1.0 + 1.0;
• Usually, the compiler is the only one who “gets to play”
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Operator Overloading
• How do you compare two objects?
Date d1, d2;
// they get values somehow
if (d1.equals(d2))
{
// something
}
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Operator Overloading
• Wouldn’t this be nicer?
Date d1, d2;
// they get values somehow
if (d1 == d2)
{
// something
}
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Operator Overloading
• How about this?
Date d1, d2;
// they get values somehow
if (d1 != d2)
{
d1 = d2 + 3;
}
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
How do you overload an operator?
• You write a function• The name is operator followed by the symbol
operator+
operator==
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Where does the function go?
• For binary operators:
class A, B;
A a;
B b;
// give them values somehow
int x = a + b;
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Operator Overload as Member Function
// in A.hclass A{// whatever else it hasint operator+(B b);};
// in A.cppint A::operator+(B b){ // something}
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Operator Overload as Global Function
// not in any class
int operator+(A a, B b);
• Typically the declaration is in the header file for A and the implementation is in the implementation file for A
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Operator Overload as Global Function
// in A.hclass A{// whatever else it has};int operator+(A a, B b);
// in A.cppint operator+(A a, B b){ // something}
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Your class isn’t always on the left
class A;
A a;
int x = A + 2;
int y = 2 + A;
• What functions does the compiler look for?
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Your class on the left
int x = A + 2;
• A::operator+(int i)
• operator+(A a, int i)
• The choice is yours
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Your class on the right
int x = 2 + A;
• int::operator+(A a) – Not possible!
• operator+(int i, A a)– Your only choice
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Coding a Global Operator
• Sometimes it’s easy:class A{private: int x;public: int operator+(int arg);//other stuff};int operator+(int arg, A a);
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Coding a Global Operator
• Here’s a neat trick
int A::operator+(int arg);
{
return x + arg;
}
int operator+(int arg, A a);
{
return a + arg;
}
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Coding a Global Operator
• Sometimes the operator is not reversible like that • The global function will need access to private
member variables of the class it works with• It needs to be an honourary member of the class
– friend
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Where does the function go?
• For unary operators:
class U;
U u1, u2;
// give them values somehow
u2 = !u1;
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Operator Overload as Member Function
// in U.hclass U{// whatever else it hasU operator!();};
// in U.cppU U::operator+(){ // something}
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Operator Overload as Global Function
// in U.hclass U{// whatever else it has};U operator!(U u);
// in U.cppU operator!(U u){ // something}
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
What can you overload?
• Binary
+ - * / %
+= -= *= /= %=
++ -- (pre and post)
^ & |
> < >= <= == !=
[]
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
What can you overload?
• Unary
+ -
!
• Some other scary ones eg &
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Operator Consistency
• Operator+ should do something that feels like adding– Matrix add, complex number add
– Container (list, queue) add an element
– String concatenate
– Increase date
• Don’t mess with people’s heads
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Operator Consistency
• If you have defined similar operators, they should work the same way.
• These three expressions should all have the same result:
A a;
a = a + 1;
a += 1;
a++;
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Tip
• Use one operator to implement the others:
bool A::operator==(const A& arg)
{ // whatever
}
bool A::operator!=(const A& arg)
{
return !(*this == arg);
}
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
More Rules
• You can’t change the order of operations
• You can’t invent new operators, including unary versions of binary-only operators such as /.
• You can’t overload operators that work on only fundamental types:int operator+(int i, int j)
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Overloading <<
cout << “my number is “ << 3 << endl;Employee e;cout << e << endl;
• Compiler is looking for
ostream& operator<<(ostream& o, Employee e)
• Typically the code is just like a display() function• Return the ostream& that was passed
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Simple Array Class
• Implement an Array class with – Range checking
– Array assignment
– Arrays that know their size
– Outputting entire arrays with <<
– Array comparisons with == and !=– Element access with []
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
array.hclass Array { friend ostream& operator<<( ostream& o, const Array& a);public: Array( int size = 10 ); Array( const Array& a); //copy constructor ~Array(); int getSize() const { return size; } const Array& operator=( const Array& a); bool operator==( const Array& a) const; bool operator!=( const Array& right ) const { return !( *this == right ); } int& operator[]( int ); const int& operator[]( int ) const; private: int size; int* ptr; // pointer to actual content};
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Using the Array class
int main(){ Array integers1(7), integers2; cout << "integers1:" << integers1 << endl; cout << "integers2:" << integers2 << endl; integers1[5] = 1000; cout << integers1[5] << endl; if ( integers1 == integers2 ) cout << "They are equal\n\n"; else cout << "They are not equal\n"; return 0;}
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Implementing Array - constructor
Array::Array( int arraySize )
{
size = ( arraySize > 0 ?
arraySize : 10 );
ptr = new int[ size ];
for ( int i = 0; i < size; i++ )
ptr[ i ] = 0;
}
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Implementing Array - destructor
Array::~Array()
{
delete [] ptr;
}
• Whenever your destructor does something destructive, you must code a copy constructor and an assignment operator
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Destructive Destructors
• Not all classes have a destructor that actually cleans up– Free memory– Close file– Release lock or database connection or ...
• When the destructor cleans up you need to be sure it will never go off accidentally
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Shallow and Deep Copies
• An object holds a resource (pointer to memory, name of file, pointer to connection object)
• If you copy the object bit-for-bit, now two objects hold the same pointer (or handle or name or whatever)
• When one goes out of scope, the destructor cleans up– The other has a pointer to nowhere!
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Implementing Array – copy constructor
Array::Array( const Array& init ) : size( init.size ), ptr(new int[init.size])
{
for ( int i = 0; i < size; i++ )
ptr[i] = init.ptr[i];
}
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Copy Constructor takes a reference
• Imagine this code:
Array a2(a1);• This uses the copy constructor to construct a2• Takes by value: need to make a copy of a1 to pass
to the function– Use the copy constructor.
– But that takes by value, so need to make a copy• Use the copy constructor
• . . .
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Implementing Array – assignment operator
const Array& Array::operator=( const Array right ){ // always check for self-assignment if ( &right != this ) { if ( size != right.size ) { delete [] ptr; size = right.size; ptr = new int[ size ]; } for ( int i = 0; i < size; i++ ) ptr[ i ] = right.ptr[ i ]; } return *this; // enables x = y = z;}
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Copy Constructor vs Assignment operator
• It’s not about whether the = operator is used• It’s about whether something is being constructed
Array a1(10);
Array a2(a1);
Array a3 = a2;
a1 = a3;
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Implementing Array – equality testbool Array::operator==( const Array& right )
const{ if ( size != right.size ) return false; // arrays of different
sizes
for ( int i = 0; i < size; i++ ) if ( ptr[ i ] != right.ptr[ i ] ) return false; // arrays are not equal
return true; // arrays are equal}
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Implementing Array – element accessint& Array::operator[]( int subscript )
{
if( subscript >= 0 && subscript < size );
return ptr[ subscript ];
else
// should throw exception or something
exit(1);
}
• Why does it return a reference?
integers1[5] = 1000;
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Implementing Arrayconst int& Array::operator[]( int subscript )
const{ if( subscript >= 0 && subscript < size ); return ptr[ subscript ]; // const reference else // should throw exception or something exit(1);}
• For use with const arrays (since it’s const)• Guarantees the object will stay const by not providing a reference to
the inside, which could be changed.
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Implementing Array
ostream& operator<<( ostream& output, const Array& a )
{
int i;
for ( i = 0; i < a.size; i++ )
{
output << a.ptr[i] << endl;
}
return output; //enables cout << x << y;
}
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
Remember The Requirements
• Implement an Array class with – Range checking
– Array assignment
– Arrays that know their size
– Outputting entire arrays with <<
– Array comparisons with == and !=– Element access with []
Monday, Feb 10, 2003 Kate Gregorywith material from Deitel and Deitel
For Next class
• Enjoy Reading Week – see you Feb 24• Read chapter 9• Do Lab 4• Study for Midterm
– Feb 24, class time, this room– Will cover everything till today– You may be asked to write code in handwriting– One hour, closed book– Worth 25%