400 likes | 630 Views
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];
E N D
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 method for(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 “+”operator objK = 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 • 下列运算符只能通过成员函数进行重载 • =、()、[]、->
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
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 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-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-write . See ReferenceCounting.cpp
Behavior of operator= • Automatic operator= creation Compiler create a = if you do not make one. See :AutomaticOperatorEquals.cpp Suggestions: • Make = by yourself. • 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. • Particular type of constructor • Overloaded operator. • Constructor conversion • a constructor • single argument an object (or reference) of another type See :AutomaticTypeConversion.cpp
Automatic type conversion • Benefits: avoid that define two overloaded versions of f( ). • Defect: 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 • ReflexivityOne 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.cppStrings2.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!