Download presentation
Presentation is loading. Please wait.
1
this, friend and operators
2
this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was called a pointer to the oblect, for which the method was called used for returning reference or pointer to the object for which the method was called used for returning reference or pointer to the object for which the method was called does not occupy memory does not occupy memory does not need to be declared does not need to be declared
3
this person & person::timeTravel(int years) { age += years; age += years; return *this; return *this;} person Boss(„John”, „Kovalsky”, 40); ( Boss.timeTravel(+20) ).timeTravel(-30)
4
friend by declaring a „friendly” code we allow accessing protected and private members of the class by declaring a „friendly” code we allow accessing protected and private members of the class
5
friend class A { friend C::theMethodNoArg(); friend C::theMethodNoArg(); // specific method (if overloaded, then with specific args) // specific method (if overloaded, then with specific args) friend class B; friend class B; // concerns whole declaration of B // concerns whole declaration of B // declarations inside B also can access // declarations inside B also can access // non-public A members // non-public A members friend fun(); friend fun(); // specific function (if overloaded, then with specific args) // specific function (if overloaded, then with specific args)}
6
friend friendship is not inheritive friendship is not inheritive friendship is not transtive friendship is not transtive friendship is declared in any section of a class (even private) friendship is declared in any section of a class (even private)
7
friend class M { friend void f() … { … } }; is equivalent to class M { friend void f(); }; void f() { … }
8
Operators What is an operator? What is an operator? a = b.val >> 4 + c * d[ e++ ]
9
Operators operator defines operations performed on its arguments and the type of the resulting expression – similarly to functions. operator defines operations performed on its arguments and the type of the resulting expression – similarly to functions. in C++ we may define operators to be used with objects (at least one argument of the operator should be an object). in C++ we may define operators to be used with objects (at least one argument of the operator should be an object).
10
Operators Most operators are overloadable Most operators are overloadable Overloading may improve performance – similarly to functions Overloading may improve performance – similarly to functions There is no obligation, and usually no need either, to define a lot of operators. Instead of operator that is used rarely it is advised to declare a method or a function There is no obligation, and usually no need either, to define a lot of operators. Instead of operator that is used rarely it is advised to declare a method or a function
11
Overloadable operators () [] -> + - ++ -- ! ~ * & new delete (typ) // unary ->* * / % + - > > >= >= == != &^|&&|| = += -= *= /= %= &= ^= |= >= // assignment
12
Operators Not overloadable operators: Not overloadable operators:..* ::?:sizeof operators to be declared exclusively as a class members: operators to be declared exclusively as a class members: ()[]->newdelete(typ)= predefined operarors (redefinable): predefined operarors (redefinable): =&
13
Associativity assignment and unary operators are of right associativity assignment and unary operators are of right associativity a=b=c is equivalent to a=(b=c) remaining ones are of right associativity remaining ones are of right associativity a+b+c is equivalent to (a+b)+c
14
Order of evaluation order of evaluation is undefined, except for: order of evaluation is undefined, except for:,||&&,||&& „, ”, „ || ”, „ && ” evaluated in the left to right order „, ”, „ || ”, „ && ” evaluated in the left to right order right arguments of operators „ || ”, „ && ” are evaluated only if necessary. right arguments of operators „ || ”, „ && ” are evaluated only if necessary.
15
Operators vs. methods different syntax for declaring, defining an callin different syntax for declaring, defining an callin no default arguments allowed (exception: function call operator) no default arguments allowed (exception: function call operator) there is a fixed number of arguments for specific operator (exception: function call operator) there is a fixed number of arguments for specific operator (exception: function call operator) there is a traditional semantics (meaning) of operators there is a traditional semantics (meaning) of operators
16
Operators If You need += then define it, If You need += then define it, defining + and = does not suffice If You need ++ then define it, If You need ++ then define it, defining + and = does not suffice Mind the traditional meaning of operators Mind the traditional meaning of operators let the unary & return the address let the unary & return the address Be cosistent Be cosistent ++i; i++; i+=1; i=i+1; // should result in the same change of i ++i; i++; i+=1; i=i+1; // should result in the same change of i
17
Operators as methods object of the class is the first argument of the operator object of the class is the first argument of the operator we declare all arguments, but the first one we declare all arguments, but the first one declaring declaring int point::operator<=(point); calling calling point point1, point2; int i= point1 <= point2; int j= point1.operator<=(point2);
18
Operators as functions at least one argument of the operator should be an object at least one argument of the operator should be an object all the arguments are operator function parameters all the arguments are operator function parameters there is no this there is no this declaring declaring int operator<=(point, point); calling calling point point1, point2; int i = point1 <= point2; int j= operator<=(point1, point2);
19
Convention for ++ and -- operator++() and operator--() are prefix ones operator++() and operator--() are prefix ones ++i--i postfix operators should be drfined using one additional unnamed int argument: postfix operators should be drfined using one additional unnamed int argument: operator++(int); operator--(int); i++i--
20
Convention for ++ and -- class X { public: X& operator++(); // prefix ++a X operator++(int); // postfix a++ }; class Y { public: }; Y& operator++(Y&); // prefix ++b Y operator++(Y&, int); // postfix b++
21
Convention for ++ and -- void f(X a, Y b) { ++a; // a.operator++(); a++; // a.operator++(0); ++b; // operator++(b); b++; // operator++(b, 0); a.operator++(); // explicit call: like ++a; a.operator++(0); // explicit call: like a++; operator++(b); // explicit call: like ++b; operator++(b, 0); // explicit call: like b++; }
22
Operators class X // members with this pointer avaliable { X* operator&();// prefix, unary, & X operator&(X);// two args X operator++(int);// suffix //X operator&(X, X);// error! 3 args //X operator/();// error! unary / ??? }; // standalone functions, no this, often friends of some class X operator-(X);// prefix, unary, - X operator-(X, X);// two args X operator--(X&, int);// suffix (post-decrementation) // X operator-(X, X, X);// error! 3 args // X operator/();// error! 0-argument operator! ;)
23
Assignment operator Define it as a nonstatic class member Define it as a nonstatic class member T& T::operator=(const T &) No initialization list, it’s not a constructor !!! No initialization list, it’s not a constructor !!!
24
Assignment operator person& person::operator=(const person &o) { if (this == &o) // Tom = Tom; if (this == &o) // Tom = Tom; return *this; return *this; delete [] name; delete [] name; name=new char[strlen(o.name) + 1]; name=new char[strlen(o.name) + 1]; strcpy(name, o.name); strcpy(name, o.name); delete [] lastName; delete [] lastName; lastName=new char[strlen(o.lastName) + 1]; lastName=new char[strlen(o.lastName) + 1]; strcpy(lastName, o.lastName); strcpy(lastName, o.lastName); age=o.age; age=o.age; return *this;// returning an object (as a reference) return *this;// returning an object (as a reference)}
25
Assignment operator why it returns a reference? why it returns a reference? we’d like to do: o1=o2=o3; we’d like to do: o1=o2=o3; person& operator=(const person&); 1. assignment to: o2 from: o3 2. assignment to: o1 from: o2 person operator=(const person&); 1. assignment to: o2 from: o3 2. copy constructor (temporary object t1 created) 3. assignment to: o1 from: t1 4. copy constructor (temporary object t2 created) 5. destructor t2 6. destructor t1
26
Assignment operator why it returns a reference? why it returns a reference? we’d like to do: o1=o2=o3; we’d like to do: o1=o2=o3; void operator=(const person&); void operator=(const person&); we may do: o2=o3; we may do: o2=o3; we cannot do: o1=o2=o3; we cannot do: o1=o2=o3;
27
Default (compiler generated) assignment operator if we do not define an assignment operator, then compiler generates one, that copies objects field by field. if we do not define an assignment operator, then compiler generates one, that copies objects field by field. it does not work for const fields it does not work for const fields it does not work for reference fields it does not work for reference fields it simply copies the pointer fields it simply copies the pointer fields
28
Stream operators Input Input friend istream & operator >>(istream &, T &); Output Output friend ostream &operator <<(ostream &, const T &);
29
Stream operators class point { int x, y; int x, y;public:… friend istream &operator >>(istream & s, point & p); friend istream &operator >>(istream & s, point & p); friend ostream &operator <<(ostream & s, const point &); friend ostream &operator <<(ostream & s, const point &);} point p, p2; cin>>p;cin>>p>>p2;cout<<p2<<p;
30
Stream operators istream & operator >>(istream & s, point & p) { s >> p.x >> p.y; s >> p.x >> p.y; return s; return s;} ostream &operator <<(ostream & s, const point & p) { s << p.x << p.y; s << p.x << p.y; return s; return s;}
31
Member access operator -> T* operator->(); T t; T t; t->m is interpreted as: t->m is interpreted as: ( t.operator-> )->m we may use object as if it was pointer we may use object as if it was pointer if operator-> returns no pointer, then if operator-> returns no pointer, then we still may use it: a=t.operator->(); we still may use it: a=t.operator->(); we cannot do: a=t->; it’s a syntax error we cannot do: a=t->; it’s a syntax error
32
Function call operator result T::operator()(args); Any number of arguments, overloadable Any number of arguments, overloadable Exception: function call operator may have default arguments Exception: function call operator may have default arguments We may use object as if it was a function We may use object as if it was a function T ob; ob(); we use it we use it when there is no appropriate operator, that we needed when there is no appropriate operator, that we needed there is a dominant method for the class (it now has no name, but is easier to call – for exaple class counter and method of incrementing) there is a dominant method for the class (it now has no name, but is easier to call – for exaple class counter and method of incrementing)
33
Index operator result T::operator[](index); Any type of result and index allowed, common sense implies integer index Any type of result and index allowed, common sense implies integer index We may use object as if it was an array We may use object as if it was an array
34
Conversion operator a.k.a. confersion function / method, a.k.a. confersion function / method, it converts object of its own class to other class it converts object of its own class to other class T::operator X(); Conversion operator of class T to the X type: Conversion operator of class T to the X type: no retrn value specified, no retrn value specified, no argument(s) specified, no argument(s) specified, declared as a class method declared as a class method
35
Conversion operator for example.: for example.: person::operator int(); conversion does not have to be explicit: conversion does not have to be explicit: person o; int i=o+5; In expressions In expressions for the specific object conversion is performed only if it is necessary, for the specific object conversion is performed only if it is necessary, no more than one conversion per single argument no more than one conversion per single argument no ambiguity allowed no ambiguity allowed
36
Conversion operator for example for classes A, B and C, conversion operators B::operator A() and C::operator B(); are defined for example for classes A, B and C, conversion operators B::operator A() and C::operator B(); are defined int f(A a); A a; B b; C c; f(a); // ok.. f(b); // f(A(b)) // f(c); // there is no operator C::operator A() // compiler cannot interpret this as f(A(B(c))) // (2 conversions of single argument)
37
Conversion operator For converting objects of one type into other type we could use a constructor, however: For converting objects of one type into other type we could use a constructor, however: this way we could not convert to fundamental type (like: int, it’s not a class), this way we could not convert to fundamental type (like: int, it’s not a class), this way we could not convert to already defined class without redefining it. this way we could not convert to already defined class without redefining it.
38
Example class counter { int cnt; int cnt; public: public: counter(int i=0):cnt(i){}; counter(int i=0):cnt(i){}; int operator()(int =1); // increment by arg. or by 1 int operator()(int =1); // increment by arg. or by 1 operator int(); // convert to int operator int(); // convert to int operator double(); // convert to double operator double(); // convert to double counter &operator+=(int); counter &operator+=(int); friend counter operator+(int, counter); // int+counter, friend friend counter operator+(int, counter); // int+counter, friend counter operator+(int); // counter+int counter operator+(int); // counter+int int operator++();// ++counter int operator++();// ++counter int operator++(int);// counter++ int operator++(int);// counter++};
39
Example inline int counter::operator ()(int i) { return cnt+=i; return cnt+=i;} inline counter::operator int() { return cnt; return cnt;} inline counter::operator double() { return double(cnt); return double(cnt);}
40
Example counter & counter::operator +=(int i) { cnt+=i; // operator()(i); (*this)(i) cnt+=i; // operator()(i); (*this)(i) return *this; return *this;} counter operator+(int i, counter l) { l+=i; // friend was not necessary l+=i; // friend was not necessary return l; return l;}
41
Example counter counter::operator +(int i) { counter l=*this; counter l=*this; l+=i; l+=i; return l; return l;} int counter::operator ++() { cnt+=1; cnt+=1; return cnt; return cnt;} int counter::operator ++(int) { int ret=cnt; int ret=cnt; cnt+=1; cnt+=1; return ret; return ret;}
42
Example class complex { double re, im; double re, im;public: complex(double re, double im):re(re), im(im) {}; complex(double re, double im):re(re), im(im) {}; complex & operator = (const complex &c); complex & operator = (const complex &c); complex & operator += (const complex &c); complex & operator += (const complex &c); complex operator + (const complex &); complex operator + (const complex &); friend complex & operator -= (complex &, const complex &); friend complex & operator -= (complex &, const complex &); friend complex operator - (const complex &, const complex &); friend complex operator - (const complex &, const complex &); friend istream & operator >>(istream &, complex &); friend istream & operator >>(istream &, complex &); friend ostream & operator <<(ostream &, const complex &); friend ostream & operator <<(ostream &, const complex &);};
43
Example complex & complex::operator = (const complex &c) { re=c.re; re=c.re; im=c.im; im=c.im; return *this; return *this; }
44
Example complex & complex::operator += (const complex &c) { re+=c.re; re+=c.re; im+=c.im; im+=c.im; return *this; return *this; } inline complex complex::operator + (const complex & c) { return complex(re+c.re, im+c.im); // complex(double, double) return complex(re+c.re, im+c.im); // complex(double, double)}
45
Example inline complex & operator-=(complex & c1, const complex & c2) //friend { c1.re-=c2.re; c1.re-=c2.re; c1.im-=c2.im; c1.im-=c2.im; return c1; return c1;} complex operator-(const complex & c1, const complex & c2) //friend { complex c=c1; complex c=c1; c-=c2; c-=c2; return c; return c;}
46
Example istream & operator >>(istream & s, complex & c) { s >> c.re >> c.im; s >> c.re >> c.im; return s; return s;} ostream &operator <<(ostream & s, const complex & c) { s << c.re << c.im; s << c.re << c.im; return s; return s;}
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.