Upload
umeko
View
96
Download
1
Embed Size (px)
DESCRIPTION
C++ 程序语言设计. Chapter 11: Operator Overloading. Outline. Operator overloading Using of friends Overload “
Citation preview
C++ 程序语言设计
Chapter 11: Operator Overloading
Outline Operator overloading Using of friends Overload “<<” operator
thinking about “*” and “+”
How many methods to use “*”? 5 * 3; int* point;
How about operator “+”?int i, j, k;k = i + j;int i[10], j[10], k[10];K = i + j;//is it right?, how to do it?
operator and function call
another way to make a function call differences between operator and
function call: The syntax is different The compiler determines which
“function” to call.double i, j, k; k = i + j;float i, k; int j; k = i + j;
add arrays each other
Normal methodfor(int num = 0; num < 10; num ++) {
k[num] = i[num] + j[num];}
Define a class for array, use member function addsum()
objK = objI.addsum(objJ);
Overload “+”operatorobjK = objI + objJ;
Warning & reassurance make the code involving your class easier
to write and especially easier to read. Make your operator overloading
reasonable. All the operators used in expressions that
contain only built-in data types cannot be changed. “1 << 4”
Only an expression containing a user-defined type can have an overloaded operator.
Syntax
operator@(argument-list) @ represents the operator that’s being
overloaded The number of arguments in the
overloaded operator’s argument list depends on two factors: Whether it’s a unary operator or a binary
operator. Whether the operator is defined as a global
function or a member function.
Syntax
class Salesperson{float money;Salesperson operator+(const Salesperson &) const;
} district2, sid, sara;
district2 = sid + sara;district2 = sid.operator+(sara);
Example-count time
5 hours, 40 minutes+ 2 hours, 55 minutes= 8 hours, 35minutes
See the file: time0.*, time1.*, time2.*
the restrictive use
cannot combine operators that currently have no meaning (such as ** )
cannot change the evaluation precedence of operators
cannot change the number of arguments required by an operator
至少必须有一个操作数是用户定义类型
the restrictive use
不能违反运算符原来的语法规则 不能重载下面的操作符:
sizeof 、 . 、 .* 、 :: 、 ?: 、 const_cast 、 dynamic_cast 、 reinterpret_const 、 static_cast
下列运算符只能通过成员函数进行重载 = 、 () 、 [] 、 ->
Operators can be overloaded
+ - * / % &
| -= ! = < >
+= /= %= ^= &= |=
<< >> == != <= >=
&& || ++ -- -> ->*
() [] , <<= >>= new
delete new[] delete[] *=
Using of friends
A = B * 2.75=> A = B.operator*(2.75)
A = 2.75 * B=> A = operator*(2.75, B)
Using of friends
friend Time operator*(double, const Time&);Time operator*(double mult, const Time& t){
Time result;long totalminutes = t.hours * mult * 60 + t.minutes * mult;result.hours = totalminutes / 60;result.minutes = totalminutes % 60;return result;
}
Overload “<<” operator
设 trip 是一个 Time 对象,显示 Time 的值: trip.Show(); cout << trip;
cout << “hello world” << endl; 必须使用友元函数,否则
trip << cout;void operator<<(ostream& os, const Time& t){
os << t.hours << " hours, " << t.minutes << " minutes" << endl;}
cout << “trip time: ” << trip << “!”;
成员函数与非成员函数的比较 对于多数运算符,可以选择使用成员函数和
非成员的友元函数实现运算符重载。Time operator+(const Time&) const;friend Time operator+ (const Time& , const Time&);
A = B + C=>
A = B.operator+(C)A = operator+(B, C)
Non-member operators
Basic guidelines
Operator Recommended use
All unary operators member
= ( ) [ ] –> –>* must be member
+= –= /= *= ^= &= |= %= >>= <<=
member
All other binary operators non-member
Unary operators
the syntax to overload all the unary operators
See the file:OverloadingUnaryOperators.cpp
Increment & decrement
friend function ++a => operator++(a) a++ => operator++(a, int)
member function ++b => B::operetor++() b++ => B::operator++(int)
Binary operators
the syntax to overload all the Binary operators
See the file:IntegerTest.cpp, ByteTest.cpp
self-assignment
all of the assignment operators have code to check for self-assignment
The most important place to check for self-assignment is operator= because with complicated objects disastrous results may occur
handle a single type, also possible to handle mixed types
Arguments & return values
function argument not change : const reference left-hand argument : not const const member function
the type of return value depends on the expected meaning of the
operator returned by value as a const
Arguments & return values
all the assignment operators modify the lvalue, the return value for all of the assignment operators should be a nonconst reference to the lvalue
the logical operators get at worst an int back, and at best a
bool
Arguments & return values
increment and decrement operators Understand the meanings of them Both of them are const ++a (a pre-increment), it generates a
call to operator++(a); but when it sees a++, it generates a call to operator++(a, int).
Arguments & return values
return by value as const Matching the temporary object.
f(a+b) When you send message to return
value, can just call the const member function.(a+b).g( )
the return optimization return Integer(left.i + right.i);
building the object directly into the location of the outside return value.
requires only a single ordinary constructor call no copy-constructor no destructor call
Integer tmp(left.i + right.i);return tmp; created the tmp object the copy-constructor copies the tmp to the
location of the outside return value call the destructor
Unusual operators
The subscript operator[ ] must be a member function and it
requires a single argument the object it’s being called for acts like
an array often return a reference be conveniently used on the left-hand
side of an equal sign
Unusual operators Operator->
used when you want to make an object appear to be a pointer
must be a member function additional, atypical constraints :
must return an object (or reference to an object) that also has a pointer dereference operator
must return a pointer that can be used to select what the pointer dereference operator arrow is pointing at
see the file :SmartPointer.cpp
Unusual operators
Operator->* provided for those situations to mimic
the behavior provided by the built-in pointer-to-member syntax
must first create a class with an operator( )
see the file :PointerToMemberOperator.cpp
Overloading assignment Understand the assignment in C++ MyType b; MyType a = b; a = b;
initializing an object using an = ,copy-constructor will be called.
See CopyingVsInitialization.cpp When dealing with the = sign
If the object hasn’t been created yet, initialization is required
otherwise the assignment operator= is used.
Behavior of operator= = can be only a member functionmember function.
objA = 5; 5 = objA; must copy all of the necessary information from the
right-hand object into the current object .See SimpleAssignment.cpp
Avoid situation of self-assignmentself-assignment . Pointers in classes if the object contains pointers to other objects .
Simply copying a pointer means that you’ll end up with two objects pointing to the same storage location. You must deal with this things.
Behavior of operator= two common approaches to this problem:
1. copy whatever the pointer refers to when you do an assignment or a copy-construction.
see :CopyingWithPointers.cpp 2. Reference Counting copy-construction or assignment means attaching another
pointer to an existing object and incrementing the reference count . Save the memory and reduce the initialization overhead. Destruction means
Reduce the reference count destroying the object if reference count = 0; Use copy-on-writecopy-on-write .
See ReferenceCounting.cpp
Behavior of operator=
Automatic operator= creationCompiler create a = if you do not make one.See :AutomaticOperatorEquals.cpp
Suggestions:1. Make = by yourself.2. If you donot want to use it . declare
operator= as a private function.
Automatic type conversion In C /C++ , compiler can auto convert type
for expression and function call. In C++, define auto type conversion
functions for class to convert type.1. Particular type of constructor 2. Overloaded operator.
Constructor conversion a constructor single argument an object (or reference) of
another type See :AutomaticTypeConversion.cpp
Automatic type conversion BenefitsBenefits: avoid that define two
overloaded versions of f( ). DefectDefect: hidden the constructor call to
Two Preventing constructor conversion sometimes constructor conversion can cause problems
to turn it off use the keyword : explicit Means do not use the constructor to do auto
conversion It is only to specify constructor.
See :ExplicitKeyword.cpp
Automatic type conversion Operator conversion
Use operator to define a overloading operator.
operator followed by the type you want to convert to .
It is unique for there is not a return type . The return is the name you’re overloading. Maybe some compiles do not support it.
See : OperatorOverloadingConversion.cpp
Automatic type conversion Reflexivity
One of the most convenient reasons to use global overloaded operators is for : automatic type conversion may be applied to either
operand. Member function can only to right hand operand. left-
hand operand must already be the proper type. See :ReflexivityInOverloading.cpp “1-1;”???
Type conversion example see :Strings1.cpp Strings2.cpp
Automatic type conversion Pitfalls in automatic type conversion
You should design your conversions correctly. otherwise compiler must choose how to quietly
perform a type conversion There are two ways:
1. Constructor . 2. Operator .
see : TypeConversionAmbiguity.cpp TypeConversionFanout.cpp
Automatic type conversion Hidden activities Automatic type conversion can introduce more
underlying activities than you may expect. see :CopyingVsInitialization2.cpp be award of the synthesized auto calls by compiler
The default constructor copy-constructor operator= destructor .
Automatic type conversion should be used carefully
next…
Dynamic Object Creation
thanks!