Presentation is loading. Please wait.

Presentation is loading. Please wait.

OOP Egar 2008 – Recitation 41 Object Oriented Programming Spring 2006 Recitation 6.

Similar presentations


Presentation on theme: "OOP Egar 2008 – Recitation 41 Object Oriented Programming Spring 2006 Recitation 6."— Presentation transcript:

1 OOP Egar 2008 – Recitation 41 Object Oriented Programming Spring 2006 Recitation 6

2 OOP Egar 2008 – Recitation 42 Friends

3 OOP Egar 2008 – Recitation 43 Non-member Private Access Sometimes we need to “break” the encapsulation of a class – allow a non- member function access to private parts. For example, operator+() should not be a member function, but it might need access to implementation. C++ allows the class to declare some function as its friend, thus allowing access to private parts.

4 OOP Egar 2008 – Recitation 44 Friend Function Adding keyword friend before function name in a class definition implies that this function is friend of the class rather than member. The function still needs to be defined. class Complex { friend const Complex operator+(const Complex&, const Complex&); }; operator+() above is not a member function of Complex (we can’t call c.operator+() for Complex c ), but it can access private parts of Complex.

5 OOP Egar 2008 – Recitation 45 Friend Class A class can declare another class’s method as friend : class A { friend void B::stop(); }; class B { void stop(); }; If all methods of one class need to be friend s of another, the whole class can be declared friend : class A { friend class B; };

6 OOP Egar 2008 – Recitation 46 Technicalities friend ship is not transitive. A friend of a friend is not (necessarily) a friend. It doesn’t matter if the friend declaration is made in the public or private parts (public is better). If the friend function is itself a method of another class, it doesn’t matter if it is in the public or private parts. Don’t declare everything friend just because you can.

7 OOP Egar 2008 – Recitation 47 Operator Overloading

8 OOP Egar 2008 – Recitation 48 The “Old” Matrix Consider class Matrix that implements a 2D matrix of integers. It supports all the usual operations – arithmetics, printing, indexing, assigning. Its use looks like: Matrix m1, m2, m3; m3.copy(m1); m3.add(m2); m3.print(); cout << m1.index(5, 5);

9 OOP Egar 2008 – Recitation 49 The “New” Matrix It’s much more natural to use standard notation: +, *, <<, = … These are called operators, and in C++ the programmer can define new meanings for them – this is called operator overloading. Now the usage is more natural: Matrix m1, m2, m3; m3 = m1 + m2; cout << m3; cout << m1(5, 5);

10 OOP Egar 2008 – Recitation 410 Syntax An overloaded operator is simply a function with funny name and calling syntax. It can implement any behavior we want ( + can subtract, etc.) Name for the function that implements + is operator+() and it can be called either by m1 + m2; or by operator+(m1, m2); Basically, the compiler replaces the former form by the latter.

11 OOP Egar 2008 – Recitation 411 Two Forms of An Operator Just as any function, an operator can be defined as a non-member function, or as a class method. If a compiler sees m1 + m2; it looks for operator+ in m1 ’s class and writes m1.operator+(m2); and for non-member operator+ and writes operator+(m1, m2); If both exist, overloading resolution is used.

12 OOP Egar 2008 – Recitation 412 Binary and Unary A binary operator takes two arguments (such as +, -, < ). A unary operator takes one argument (such as ++, ! ).

13 OOP Egar 2008 – Recitation 413 Overloadable Binary These binary operators can be overloaded: +-*/% &|^ =+=-=*=/=%=<<=>>=&=|=^= <<=>>===!= []() ->*->, <<>>&&||

14 OOP Egar 2008 – Recitation 414 Overloadable Unary These unary operators can be overloaded: ~!-+ &*newnew[]deletedelete[] ++ (prefix)++ (postfix)-- (prefix)-- (postfix)

15 OOP Egar 2008 – Recitation 415 Non-overloadable These operators cannot be overloaded: ::..*sizeoftypeid?:

16 OOP Egar 2008 – Recitation 416 Binary Looks and Calling A binary operator can be defined by either –a non-static member function taking one argument of any type, –or a non-member function taking two arguments of any type. Return type can be anything. For a binary operator@, a@b can be interpreted either as a.operator@(b) or as operator@(a, b).

17 OOP Egar 2008 – Recitation 417 Unary Looks and Calling A unary operator can be defined by either –a non-static member function taking no arguments, –or a non-member function taking one argument of any type. Return type can be anything. For a unary operator@, @a can be interpreted either as a.operator@() or as operator@(a).

18 OOP Egar 2008 – Recitation 418 Must-be Members These operators must be non-static member functions of a class: – operator= – operator[] – operator() – operator-> This is to ensure that their first operand is lvalue. All the rest can be either member or non- member.

19 OOP Egar 2008 – Recitation 419 Example Implementation Class TextNum

20 OOP Egar 2008 – Recitation 420 TextNum ’s Description Let’s implement a class that holds a text description of an integer. A TextNum can be printed, assigned to, added/multiplied (etc.), compared, incremented, negated, indexed, and more…

21 OOP Egar 2008 – Recitation 421 Basic Definition class TextNum { public: TextNum(int); TextNum(const TextNum&); int to_int() const; string to_string() const; private: string _textNum; int _num; string intToString(int); };

22 OOP Egar 2008 – Recitation 422 Binary Operator+() const TextNum operator+ (const TextNum& lhs, const TextNum& rhs) { return lhs.to_int() + rhs.to_int(); }

23 OOP Egar 2008 – Recitation 423 Commutativity and Implicit Conversions If operator+ is a member function, we have a problem: TextNum t1; int i; t1 + i;// FINE, means t1.operator+(i), i is // implicitly converted to TextNum i + t1;// ERROR, not int::operator+() nor // operator+(TextNum,TextNum) exist Making an operator a non-member function allows implicit type conversions on the first argument: t1 + i;// operator+(t1, i) i + t1;// operator+(i, t1) // both times i is implicitly // converted to TextNum

24 OOP Egar 2008 – Recitation 424 Operator==() bool operator== (const TextNum& lhs, const TextNum& rhs) { return lhs.to_int() == rhs.to_int(); }

25 OOP Egar 2008 – Recitation 425 Operator<<() ostream& operator<< (ostream& output, const TextNum& rhs) { output << rhs.to_string(); return output; }

26 OOP Egar 2008 – Recitation 426 Operator<<() as Non-member Shifting operator ( >>, << ) are commonly used in C++ for input/output operations. operator<<() need not be commutative, but still we declare it non-member. This is because otherwise it would have to be called like this: t1 << cout;// t1.operator<<(cout);

27 OOP Egar 2008 – Recitation 427 Unary Operator-() TextNum TextNum::operator-() { return -_num; }

28 OOP Egar 2008 – Recitation 428 Prefix and Postfix Operator++() // Prefix TextNum& TextNum::operator++() { _textNum = intToString(++_num); return *this; } // Postfix const TextNum TextNum::operator++(int) { TextNum old = *this; ++(*this); return old; }

29 OOP Egar 2008 – Recitation 429 Prefix and Postfix Unary operator++() and operator--() can be either prefix ( ++i ) or postfix ( i++ ). Overloaded postfix operator has a dummy int parameter that is not used. Prefix operator should return a reference to this, while postfix should return a const copy of the old state.

30 OOP Egar 2008 – Recitation 430 Operator=() and Operator+=() TextNum& TextNum::operator=(const TextNum& rhs) { _num = rhs._num; _textNum = rhs._textNum; return *this; } TextNum& TextNum::operator+=(const TextNum& rhs) { _num += rhs._num; _textNum = intToString(_num); return *this; }

31 OOP Egar 2008 – Recitation 431 Assignment operator=() is called assignment operator. If it is not defined for a class, compiler will automatically generate one (if needed). By a strange turn of fate, operator=() must be a member function, while operator+=(), etc. can be a non-member function. Assignment operators should return a reference to *this.

32 OOP Egar 2008 – Recitation 432 Assignment operator Make sure to return a reference to the objects to allow chaining. May be weird (a=b)=c but this is how int works. MAKE SURE TO CHECK FOR SELF ASSIGNMENT! If your class using dynamic allocated data then obj=obj //KABOOM!!!

33 OOP Egar 2008 – Recitation 433 Operator[]() // non-const char& TextNum::operator[](size_t idx) { return _textNum[idx]; } // const const char& TextNum::operator[](size_t idx) const { return _textNum[idx]; }

34 OOP Egar 2008 – Recitation 434 Subscripting Operator[]() allows subscripting: t1[10] = 'M‘; Usually, both non- const and const versions should be provided – the former allows changing the contents, while the latter allows access when the object is const.

35 OOP Egar 2008 – Recitation 435 Operator()() const string TextNum::operator()(size_t start, size_t end) { return _textNum.substr(start, end-start+1); }

36 OOP Egar 2008 – Recitation 436 Function Call operator()() is called function call operator. cout << t1(0, 5); The above looks just like a call to a function named t1() with arguments 0 and 5. This allows creating functors – objects that act like functions. We will see their use in STL. operator()() can have any number of parameters. This allows subscripting with more that one index (useful in matrices, for example).

37 OOP Egar 2008 – Recitation 437 A Word of Warning Never overload &&, || or, This is because C++ employs short-circuit evaluation of boolean expressions: char *p; if ( (p!=0) && (strlen(p) > 5) ) … –If p is 0, strlen() is never called. But overloading changes the syntax to function call syntax, and in function call all parameters must be evaluated before the call.

38 OOP Egar 2008 – Recitation 438 Example TextNum Program TextNum t1(-1032), t2(32); cout << t1 << endl; cout << t1 + t2 << endl; ++t1; t2--; if (t1 < t2) { cout << t1 << " is less than " << t2 << endl; } else { cout << t1 << " is more than " << t2 << endl; } cout << 'Z' << (t1 + t2 + 1000)(1,3) << endl;

39 OOP Egar 2008 – Recitation 439 Output minus one thousand thirty two minus one thousand minus one thousand thirty one is less than thirty one Zero

40 OOP Egar 2008 – Recitation 440 More on operator overloading Here: http://www.parashift.com/c++-faq- lite/operator-overloading.htmlhttp://www.parashift.com/c++-faq- lite/operator-overloading.html


Download ppt "OOP Egar 2008 – Recitation 41 Object Oriented Programming Spring 2006 Recitation 6."

Similar presentations


Ads by Google