Overloading Conversion Operators

advertisement
CISC/CMPE320
• RAD due Friday in your Wiki.
• Presentations week 6 – next week. Schedule on
next slide.
• Today:
– Operator Overloading, Cont.
Fall 2015
CISC/CMPE320 - Prof. McLeod
1
Presentation Schedule – Week 6
• Tuesday, Oct. 20 – Basswood, Beech, Cherry,
Walnut.
• Thursday, Oct. 22, Lecture Time – Hickory,
Maple, Oak, Birch.
• Thursday, Oct. 22, Tutorial Time (room TBA) –
Poplar, BalsamFir, Spruce, Cedar.
• Friday, Oct. 23 – Hemlock, JackPine, Tamarack,
WhitePine.
Fall 2015
CISC/CMPE320 - Prof. McLeod
2
MyComplex Class Demo
• See the start of a simple class to hold complex
numbers: myComplex.h and myComplex.cpp:
• First version uses non-member overloading and
accessors.
• Second version uses member overloading of the
+ operator.
• Third version uses non-member friends and no
accessors.
Fall 2015
CISC/CMPE320 - Prof. McLeod
3
Version 3, Observations
• “friend” functions are declared in the scope of the
class but are implemented like non-member
functions. They can see private members of
instances of the class they are “friends” with.
• A friend function cannot access the private
members of its friend object, because it is not a
member of that object. You don’t need, and
cannot, declare them as const.
Fall 2015
CISC/CMPE320 - Prof. McLeod
4
Summary of MyComplex, So Far
• Mixed type expressions (using your object) need
conversion constructors, that will be invoked
automatically to match types before the operator
is evaluated.
• If you are going to use your binary operators in
mixed type expressions it is best to overload them
as non-member functions.
• If you do not wish to provide accessors, then nonmember functions will have to be declared as
friends.
• So, we know how to overload the binary
arithmetic operators and <<.
Fall 2015
CISC/CMPE320 - Prof. McLeod
5
Member or Non-Member Overloading?
• You will probably need to use both kinds.
• For example, assignment operators must be
member functions, because you need to modify
the LHS.
• Non-member functions cannot access private
things in the class. A friend function can access
private members from instances.
Fall 2015
CISC/CMPE320 - Prof. McLeod
6
Overloading Arithmetic Operators
• Binary: + - * / and %
– Easy to do. Usually a non-member function will
be best if you can use accessors for the
private stuff (or are a friend function).
• Unary: - * and & (negation, pointer de-reference,
address-of operator).
– Also easy. If a non-member function, you only
need a single parameter. A member function
does not need any.
Fall 2015
CISC/CMPE320 - Prof. McLeod
7
Overloading Boolean Operators
•
•
•
•
==, <, >, <=, >=, !=
Normally a non-member function.
Return a bool.
Consider writing a member function called
something like “compare” that returns an int.
• compare will take two objects and return a
negative int if the first is less than the second,
zero if they are equal and a positive int if the first
is greater than the second.
• The other comparison operators can invoke
compare.
Fall 2015
CISC/CMPE320 - Prof. McLeod
8
Overloading Input and Output
• Stream output: <<
• This operator takes the RHS, adds it to the stream
obtained as the LHS and then returns this stream.
• As a non-member function:
ostream& operator<<(ostream& out, const MyClass myC) {
out << myC.convert();
return out;
}
• convert() changes myC to something that can
normally be handled by << (an atomic type, a
string or a *char).
Fall 2015
CISC/CMPE320 - Prof. McLeod
9
Overloading Input and Output, Cont.
• Stream input: >>
• As for output except you use istream& instead
of ostream&.
Fall 2015
CISC/CMPE320 - Prof. McLeod
10
Aside – Converting Between Strings and Numbers
• Applies to C++98:
• Use the stringstream stream
(#include <sstream>)
• See StringNumberConversion.cpp
• These functions also provide a “pre-look” at how
to code with templates. (Like “generics” in Java).
Gets around the problem of having to write
separate functions for each numeric type.
• Avoids the use of C functions like atof() and atoi()
in <cstdlib>.
Fall 2015
CISC/CMPE320 - Prof. McLeod
11
Converting Between Strings and Numbers, Cont.
• Should be much nicer now in C++11
• The <string> library has built-in functions for conversions
in both directions.
• See the <string> library docs.
• The current distro. (4.8.1) of MinGW still does not support
the string conversion functions. But you can download a
patch:
http://tehsausage.com/mingw-to-string
• And follow the instructions on this site.
• This: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52015
says that the bug is fixed for 64 bit versions of MinGW
only.
Fall 2015
CISC/CMPE320 - Prof. McLeod
12
Overloading Increment and Decrement
• Operators ++ and -• Pre-increment, ++x, increments by one then
returns the value.
• Post-increment, x++, returns the value then
increments by one.
• Member functions:
MyClass& operator++(); // pre-increment
MyClass operator++(int unused); // post-increment
• In the pre-increment form, use return *this;
to return a reference to the current object.
Fall 2015
CISC/CMPE320 - Prof. McLeod
13
Overloading Assignment Operators
• The = operator is automatically generated for you,
so you don’t have to overload it.
• By default the assignment operator carries out
member-wise assignment.
• As long as you don’t have to carry out any
dynamic memory management tasks with the
heap, the default = should be fine.
• However you will still have to overload the
combined assignment operators such as +=, -=,
*=, /=, etc.
• (Invoke the binary operators…)
Fall 2015
CISC/CMPE320 - Prof. McLeod
14
MyComplex Demo, Again
• See “version 4”: overloads ++ and +=.
• Which is faster? Pre-increment or postincrement?
Fall 2015
CISC/CMPE320 - Prof. McLeod
15
Overloading Conversion Operators
• You don’t need to write these for assignment 2.
• Consider that your Fraction class has top for the
numerator and bottom for the denominator.
• To overload a cast to type double:
Fraction::operator double() const {
return static_cast<double>(top) / bottom;
}
• If test is a Fraction object, this allows stuff like:
double aNum = static_cast<double>(test);
Fall 2015
CISC/CMPE320 - Prof. McLeod
16
Overloading Conversion Operators, Cont.
• Similarly for int.
• Note the lack of return type.
• But if you have a conversion operator and an
applicable conversion constructor this leads to an
ambiguity:
• Which operator should be used in a mixed type
expression?
• See MyComplexAmbiguous
Fall 2015
CISC/CMPE320 - Prof. McLeod
17
Overloading Conversion Operators, Cont.
• With just the constructor you can do things like:
int aVal = 10;
Fraction test = static_cast<Fraction>(aVal);
• Same as:
Fraction test = Fraction(aVal);
• But you can’t do:
aVal = static_cast<int>(test);
Fall 2015
CISC/CMPE320 - Prof. McLeod
18
Overloading Conversion Operators, Cont.
• So, what’s to do?
• If you ditch the one number constructor, then you
give yourself a lot more work when you need to
overload operators for mixed expressions.
• Might be easiest to keep the constructor and
compromise.
• Write member functions called intVal() and
doubleVal() instead?
• Or declare the constructor explicit?
Fall 2015
CISC/CMPE320 - Prof. McLeod
19
The explicit Keyword
• If you want a constructor to just be a constructor
and not for use as a rule for implicit type
conversions, declare it with explicit.
• For example:
class Fraction {
// etc.
explicit Fraction(int);
// etc.
};
Fall 2015
CISC/CMPE320 - Prof. McLeod
20
The explicit Keyword, Cont.
• If you use explicit:
• From the MyComplexAmbiguous demo, what is
the result of a mixed type expression with a
number on one side and a MyComplex instance
on the other?
Fall 2015
CISC/CMPE320 - Prof. McLeod
21
Overloading the Subscript Operator: [ ]
• Appropriate for:
– A data structure requiring access using an
index.
– A data structure that wants to make sure index
values are legal.
• See the SafeArray class.
– Note the two versions of operator[] used.
– Note the use of a friend non-member
function.
– Note the use of a destructor (getting ahead of
myself…)
Fall 2015
CISC/CMPE320 - Prof. McLeod
22
Overloading the Function Call Operator: ( )
• Allows an object to behave as if it is a function.
• Called a function object.
• The only operator where the number of
arguments is not fixed or limited to one or two.
• See the RandomInt class.
• Used in the STL.
Fall 2015
CISC/CMPE320 - Prof. McLeod
23
Aside - inline Functions
• Used in the RandomInt class.
• Used when the function body is short:
– ≤ 3 assignment statements.
– one conditional.
– one return.
• An inline function is not placed on the
activation record stack, but is expanded in place
and so is executed faster.
• Must be in declaration file.
• The downside is that a copy is made every time
the function is invoked – so it should be short.
Fall 2015
CISC/CMPE320 - Prof. McLeod
24
Download