290 likes | 305 Views
Chapter 8. Operator Overloading. User-defined Meaning for “built-in” Operators. Natural, suggestive usage Complex number addition, subtraction, etc. Semantic integrity Assignment for objects with pointers Uniformity with built-in types << operator with user defined types.
E N D
Chapter 8 Operator Overloading
User-defined Meaning for “built-in” Operators • Natural, suggestive usage • Complex number addition, subtraction, etc. • Semantic integrity • Assignment for objects with pointers • Uniformity with built-in types • << operator with user defined types
Format for Overloaded Operators Operator keyword Standard return type and Class Operator being overloaded int& Array::operator+ (int i); array1 = array2 + 10 array2.operator+(10) Parameter Parameter Parameter
Example Overloaded Operators for Array Class class Array { private: int array[20]; public: Array(int init = 0); // overload the index operator, [] int& operator[](int i); ~Array(); }; int& Array::operator[](int i) { assert(0 <= i && i < 20); return array[i]; } Interface Implementation Checks array bounds
Using Overloaded Operator Array array; array[0] = 1; array[1] = 1; // compute first twenty // Fibonnaci numbers for (int i = 2; i < 20; i++) array[i] = array[i-1] + array[i-2];
Mixing User-Defined and Built-In Operations Array safe; int regular[20]; regular[10] = safe[10]; safe[11] = regular[11]; safe[0] = safe[0] + regular[0] “Safe” array in terms of index bounds Typical array, no index bounds checking
Implementing Overloaded Operators for Arrays Index operator int& Array::operator[](int i) { assert(0 <= i && i < 20); return array[i]; }
Additional Overloaded ArrayOperators class Array { private: int array[20]; public: int& operator[](int i); // addition operator Array operator+(Array& other); // subtraction operator Array operator-(Array& other); ~Array(); }; Adding + and - operators
Implementation of + and -Overloaded Operators Array Array::operator+(Array& other) { Array result; for(int i=0; i<20; i++) result[i] = array[i] + other[i]; return result; } Array Array::operator-(Array& other) { Array result; for(int i=0; i<20; i++) result[i] = array[i] - other[i]; return result; }
Multiply Overloading an Operator class Array { private: int array[20]; public: // addition operator Array operator+(Array& other); // add increment to all Array operator+(int increment); }; Array Array::operator+(int increment){ Array result; for(int i = 0; i< 20; i++) result[i] = array[i] + increment; return result; } Both are + operators, but parameters differ
Usage of Multiply Overloaded Operators Array one(1); // all elements are 1 // add 1 to each element Array two = one + 1; // pairwise addition of Arrays one and two Array three = one + two; Can we do this? Array four = 1 + one;
When to Overload Operators with Nonmember Functions • Operators on primitive data types • E.g., int, float, arrays • Class source not always available • E.g., ostream • Type casting
operator op(Y) operator op(X,Y) Operator Lookup Rules • Suppose: • Compiler looks for ‘op’ in this order • Member function in X of form • Nonmember function of form • Return type is not part of lookup Y y; X x; x op y;
Nonmember Function Operator Overload Array operator+(int increment, Array array) { Array result; for(int i=0; i<20; i++) result[i] = array[i] + increment; return result; } Now we can do this! // add 1 to each element Array four = 1 + one;
Input-Output Using a Method class Array{ private: int array[20]; public: // ... void Print(); ~Array(); };
Input-Output Using a Method (cont’d) void Array::Print() { cout << "[ "; for(int i = 0; i < 19; i++) cout << array[i] << ", "; cout << array[19] << " ]"; } Array test; test.Print(); [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
Cool! We can write to any ostream! Defining Stream Operators ostream& operator<< (ostream& os, Array& a) { os << "[ "; for(int i = 0; i < 19; i++) os << a[i] << ", "; os << a[19] << " ]"; } ofstream outFile("array.data"); Array a; // write values of a to outfile outFile << a; // write to standard output cout << a;
Overloading Stream Operators ofstream& operator<<(ofstream& ofs, Array& a){ ofs.write((char*)(a.array), 20*sizeof(int)); return ofs; }; ofstream binaryFile("array.bin"); Array a; // write a to file in binary form binaryFile << a; binaryFile.close(); But this is private data! How do we know the binary implementation will be invoked?
Declaring a "friend" Stream I/O Operator class Array { //... friend ofstream& operator<< (ofstream& ofs, Array& a); }; But not: class Array { //... friend class ofstream; } Why not?
How do I make an overloaded << operator for my Parts Class? class Part { public: Part(PartType type, int time, int identifier, float quality); int GetTime() {return time;} int GetIdentifier() {return identifier;} PartType GetType() {return type;} float GetQuality() {return quality;} protected: PartType type; int time; int identifier; float quality; }; Show definition and declaration changes and additions.
Stream Operator for a Part/Piece Object /* This is not in the Parts class. */ ostream& operator<< (ostream &os, Part&p) { os << “ (“ << TranslateType(p.type) << “) ID# “; os << p.identifier << “ Quality: “; os << setw(4) << setprecision(2) << p.quality; os << “ Entered: “ << TranslateTime(p.time); os << “ #Recycles: << p.recycles << endl; } friend ofstream& operator<< (ofstream& ofs, Part& p); This is in the Parts class.
Have Object of Class X Type Conversion Need Object of Class Y Type Conversion
Implicit and Explicit Type Conversion int i; float f; f = i; // implicit conversion f = (float)i; // explicit conversion f = float(i); // explicit conversion
Type Conversion Have: Counter count(0); // manipulate count if ( count.Value() > 0) ... if ( count.Value() == 100) ... cout << count.Value(); Want: Counter count(0); // manipulate count if ( count > 0) ... if ( count == 100) ... cout << count;
Defining a Type Conversion Operator class Counter: public DisplayableNumber { ... public: ... operator int(); ... }; Simple int type conversion operator Used when implicit or explicit conversion done on a Counter
Constructors as Type Conversion Mechanisms class Counter : public DisplayableNumber { ... public: Counter(int i); ... }; A constructor can be viewed as a way to convert an int to a Counter.
Type Conversion andOperator Overloading • Given a class X • Conversion can be used to simplify • X + int • int + X • X + X • Provide a basic conversion from int to X
Type Conversion andOperator Overloading: Colors • Color is • Red, Green, Blue combinations • Each primary color 0 - 63 • Color something(Red(?), Green(?), Blue(?))
Type Conversion andOperator Overloading: Colors Color aqua(Red(0), Green(50), Blue(50)); Color darkRed = Red(63); Color purple = darkRed + aqua + Blue(13); Color peach = purple - Blue(13) - Green(3); Color test1 = darkRed + peach; Color test2 = peach + darkRed; cout << aqua << endl; cout << purple << endl; cout << peach << endl; cout << darkRed << endl;