46
this, friend this, friend and operators and operators

This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

  • View
    227

  • Download
    2

Embed Size (px)

Citation preview

Page 1: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

this, friend this, friend and operatorsand operators

Page 2: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

thisthis

exists in every exists in every non-staticnon-static method method a pointer to the oblect, for which the method a pointer to the oblect, for which the method

was calledwas called used for returning reference or pointer to the used for returning reference or pointer to the

object for which the method was calledobject for which the method was called does not occupy memorydoes not occupy memory does not need to be declareddoes not need to be declared

Page 3: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

thisthis

person & person::timeTravel(int years)person & person::timeTravel(int years){{ age += years; age += years; return *this; return *this; }}

person Boss(„John”, „Kovalsky”, 40);person Boss(„John”, „Kovalsky”, 40);( Boss.timeTravel(+20) ).timeTravel(-30)( Boss.timeTravel(+20) ).timeTravel(-30)

Page 4: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

friendfriend

by declaring a „friendly” code we allow by declaring a „friendly” code we allow accessing protected and private members of accessing protected and private members of the classthe class

Page 5: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

friendfriend

class class AA{{ friend C::friend C::theMethodNoArgtheMethodNoArg(); (); // 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)}}

Page 6: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

friendfriend

friendship is not inheritivefriendship is not inheritive

friendship is not transtivefriendship is not transtive

friendship is declared in any section of a class friendship is declared in any section of a class (even private)(even private)

Page 7: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

friendfriendclass M {

friend void f() { ……}

};

is equivalent tois equivalent to

class M {friend void f();

};

void f() { … }

Page 8: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

OperatorsOperators

What is an operator?What is an operator?

a = b.val >> 4 + c * d[ e++ ]a = b.val >> 4 + c * d[ e++ ]

Page 9: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

OperatorsOperators

operator operator defines operations performed on its defines operations performed on its arguments and the type of the resulting arguments and the type of the resulting expression expression – – similarly to functionssimilarly to functions..

inin C C++++ we may define operators to be used we may define operators to be used with objectswith objects ( (at least one argument of the at least one argument of the operator should be an objectoperator should be an object).).

Page 10: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

OperatorsOperators

Most operators are overloadableMost operators are overloadable

Overloading may improve performance – Overloading may improve performance – similarly to functionssimilarly to functions

There is no obligation, and usually no need There is no obligation, and usually no need either, to define a lot of operators. Instead of either, to define a lot of operators. Instead of operator that is used rarely it is advised to operator that is used rarely it is advised to declare a method or a functiondeclare a method or a function

Page 11: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

Overloadable operatorsOverloadable operators

() [] ->() [] ->+ - ++ -- ! ~ * & new delete (typ)+ - ++ -- ! ~ * & new delete (typ) // unary// unary->*->** / %* / %+ -+ -<< >><< >>< <= > >=< <= > >=== !=== !=&&^̂||&&&&||||= += -= *= /= %= &= ^= |= <<= >>= = += -= *= /= %= &= ^= |= <<= >>= // assignment// assignment

Page 12: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

OperatorsOperators Not overloadable operators:Not overloadable operators:

.. .* .* :::: ?:?: sizeofsizeof

operators to be declared exclusively as a class members:operators to be declared exclusively as a class members:

()() [][] ->-> newnew deletedelete (typ)(typ) ==

predefined operarors (redefinable):predefined operarors (redefinable):

== &&

Page 13: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

AssociativityAssociativity

assignment and unary operatorsassignment and unary operators are of right are of right associativityassociativity

a=b=c a=b=c is equivalent to is equivalent to a=(b=c)a=(b=c)

remaining onesremaining ones are of right associativityare of right associativity

a+b+ca+b+c is equivalent to is equivalent to (a+b)+c(a+b)+c

Page 14: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

Order of evaluationOrder 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 right arguments of operators „ || ”, „ && ” are evaluated only if necessary.evaluated only if necessary.

Page 15: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

Operators vs. methodsOperators vs. methods

different syntax for declaring, defining an callindifferent syntax for declaring, defining an callin

no default arguments allowed (exception: function no default arguments allowed (exception: function call operator)call operator)

there is a fixed number of arguments for specific there is a fixed number of arguments for specific operator (exception: function call operator)operator (exception: function call operator)

there is a traditional semantics (meaning) of operatorsthere is a traditional semantics (meaning) of operators

Page 16: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

OperatorsOperators If You need += then define it, If You need += then define it,

defining + and = does not sufficedefining + and = does not suffice

If You need ++ then define it,If You need ++ then define it,defining + and = does not sufficedefining + and = does not suffice

Mind the traditional meaning of operatorsMind the traditional meaning of operators let the unarylet the unary & & return the addressreturn the address

Be cosistentBe cosistent ++i; ++i; i++; i++; i+=1; i+=1; i=i+1; i=i+1; // should result in the same change of i// should result in the same change of i

Page 17: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

Operators as methodsOperators as methods object of the class is the first argument of the operatorobject of the class is the first argument of the operator we declare all arguments, but the first onewe declare all arguments, but the first one

declaringdeclaring

int point::operator<=(point);int point::operator<=(point);

callingcalling

point point1, point2;point point1, point2;int i=int i= point1point1 <=<= point2;point2;int int jj== point1.operator<=(point2);point1.operator<=(point2);

Page 18: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

Operators as functionsOperators as functions at least one argument of the operator should be an objectat least one argument of the operator should be an object all the arguments are operator function parametersall the arguments are operator function parameters there is no thisthere is no this

declaringdeclaring

int operator<=(pointint operator<=(point, point, point););

callingcalling

point point1, point2;point point1, point2;int iint i == point1point1 <=<= point2;point2;int int jj== operator<=(operator<=(point1, point1, point2);point2);

Page 19: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

Convention for Convention for ++ ++ andand -- --

operator++() operator++() andand operator operator----()() are prefix ones are prefix ones

++i++i --i --i

postfix operators should be drfined using one postfix operators should be drfined using one additional unnamed int argumentadditional unnamed int argument: :

operator++(int)operator++(int);; operatoroperator----(int);(int);

i++i++ i--i--

Page 20: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

Convention for Convention for ++ ++ andand -- --

class X {public:

X& operator++(); // prefix ++aX operator++(int); // postfix a++

};

class Y {public:};

Y& operator++(Y&); // prefix ++bY operator++(Y&, int); // postfix b++

Page 21: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

Convention for Convention for ++ ++ andand -- --

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++;

}

Page 22: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

OperatorsOperatorsclass X class X // members with this pointer avaliable// members with this pointer avaliable{{

X* operator&();X* operator&(); // prefix, unary, &// prefix, unary, &X operator&(X);X operator&(X); // two args// two argsX operator++(int);X operator++(int); // suffix// suffix

//// X operator&(X, X);X operator&(X, X);// error! 3 args// error! 3 args//// X operator/();X operator/(); // error! unary / ???// error! unary / ???};};

// standalone functions, no this, often friends of some class// standalone functions, no this, often friends of some classX operator-(X);X operator-(X); // prefix, unary, -// prefix, unary, -X operator-(X, X);X operator-(X, X); // two args// two argsX operator--(X&, int);X operator--(X&, int); // suffix (post// suffix (post--decrementation)decrementation)// X operator-(X, X, X);// X operator-(X, X, X); // error! 3 args// error! 3 args// X operator/();// X operator/(); // error! // error! 0-argument operator! ;)0-argument operator! ;)

Page 23: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

Assignment operatorAssignment operator

Define it as a nonstatic class memberDefine it as a nonstatic class member

T& T::operator=(const T &)T& T::operator=(const T &)

No initialization list, it’s not a constructor !!!No initialization list, it’s not a constructor !!!

Page 24: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

Assignment operatorAssignment operator

person& person::operator=(const person &o)person& person::operator=(const person &o){{ if (this == &o) if (this == &o) // // Tom Tom == Tom Tom;; return return *this*this;; delete delete [] [] name;name; name=new char[strlen(o.name) + 1];name=new char[strlen(o.name) + 1]; strcpy(name, o.name);strcpy(name, o.name); delete delete [] [] lastName;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;return *this; //// returning an object (as a returning an object (as a referencereference))}}

Page 25: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

Assignment operatorAssignment operator why it returns a reference?why it returns a reference?

we’d like to do:we’d like to do: o1=o2=o3; o1=o2=o3;

person& operator=(const person&);person& operator=(const person&);1.1. assignment to: assignment to: oo2 from: 2 from: oo332.2. assignment to: assignment to: oo1 from: 1 from: oo22

person operator=(const person&);person operator=(const person&);1.1. assignment to: assignment to: oo2 2 fromfrom: : oo332.2. copy constructor (temporary object t1 created)copy constructor (temporary object t1 created)3.3. assignment to: assignment to: oo1 from: t11 from: t14.4. copy constructor (temporary object t2 created)copy constructor (temporary object t2 created)5.5. destructor t2destructor t26.6. destructor t1destructor t1

Page 26: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

Assignment operatorAssignment operator

why it returns a reference?why it returns a reference? we’d like to do:we’d like to do: o1=o2=o3; o1=o2=o3;

void operator=(const person&);void operator=(const person&); we may do:we may do: o2=o3; o2=o3; we cannot do:we cannot do: o1=o2=o3; o1=o2=o3;

Page 27: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

Default (compiler generated) Default (compiler generated) assignment operatorassignment operator

if we do not define an assignment operator, if we do not define an assignment operator, then compiler generates one, that copies then compiler generates one, that copies objects field by field.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 fieldsit simply copies the pointer fields

Page 28: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

Stream operatorsStream operators

InputInput

friend friend istream & operator >>(istream &, istream & operator >>(istream &, T T &)&);;

OutputOutput

friend friend ostream &operator <<(ostream &, const ostream &operator <<(ostream &, const TT &) &);;

Page 29: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

Stream operatorsStream operators

class pointclass point{{ int x, y;int x, y;public:public:

…… friend friend istream &operator >>(istream & s, istream &operator >>(istream & s, point point & & pp));; friend friend ostream &operator <<(ostream & s, const ostream &operator <<(ostream & s, const pointpoint &) &);;}}

point p, p2;point p, p2;cin>>p;cin>>p;cin>>p>>p2;cin>>p>>p2;cout<<p2<<p;cout<<p2<<p;

Page 30: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

Stream operatorsStream operators

istream & operator >>(istream & s, istream & operator >>(istream & s, point point & & pp)){{ s >> s >> p.xp.x >> >> p.yp.y;;

return s;return s;}}

ostream &operator <<(ostream & s, const ostream &operator <<(ostream & s, const pointpoint & & pp)){{ s << s << p.xp.x << << p.yp.y;;

return s;return s;}}

Page 31: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

Member access operator ->Member access operator ->

T* operator->();T* operator->();

T t;T t; t->m is interpreted as:t->m is interpreted as:

( t.operator-> )->m( t.operator-> )->m

we may use object as if it was pointerwe 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=we still may use it: a=t.t.operator->(); operator->(); we cannot do: a=t->; it’s a syntax errorwe cannot do: a=t->; it’s a syntax error

Page 32: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

Function call operatorFunction call operator

result T::operator()(args);result T::operator()(args);

Any number of arguments, overloadableAny number of arguments, overloadable Exception: function call operator may have default argumentsException: function call operator may have default arguments We may use object as if it was a functionWe may use object as if it was a function

T ob; T ob; ob();ob();

we use it we use it when there is no appropriate operator, that we needwhen there is no appropriate operator, that we neededed there is a dominant method for the class (it now has nthere is a dominant method for the class (it now has noo name, but is name, but is

easier to call – for exaple class counter and method of incrementing)easier to call – for exaple class counter and method of incrementing)

Page 33: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

InIndedex operatorx operator

resultresult T::operator[] T::operator[](index);(index);

Any type of result and index allowed, common Any type of result and index allowed, common sense implies integer indexsense implies integer index

We may use object as if it was We may use object as if it was an arrayan array

Page 34: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

Conversion operatorConversion operator

a.k.a. confersion function / method, a.k.a. confersion function / method, it converts object of its own class to other classit converts object of its own class to other class

TT::operator ::operator XX();();

Conversion operator of class T to the X typeConversion operator of class T to the X type:: no retrn value specifiedno retrn value specified, , no argument(s) specifiedno argument(s) specified, , declared as a class methoddeclared as a class method

Page 35: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

Conversion operatorConversion operator for example.: for example.:

person::operator int();person::operator int();

conversion does not have to be explicit:conversion does not have to be explicit:person o; person o; int i=o+5; int i=o+5;

In expressionIn expressionss 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 no more than one conversion per singlesingle argument argument no ambiguity allowedno ambiguity allowed

Page 36: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

Conversion operatorConversion operator for example for classes A, B and C, conversion operators for example for classes A, B and C, conversion operators

B::operator A() and C::operator B(); are definedB::operator A() and C::operator B(); are defined

int f(A a);int f(A a);A a; B b; C c;A a; B b; C c;

f(a); f(a); // ok..// ok..f(b); f(b); // f(A(b)) // f(A(b)) // f(c); // f(c); // there is no operator C::operator A() // there is no operator C::operator A()

// compiler cannot interpret this as f(A(B(c))) // compiler cannot interpret this as f(A(B(c))) // (2 conversions of single argument)// (2 conversions of single argument)

Page 37: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

Conversion operatorConversion operator

For converting objects of one type into other For converting objects of one type into other type we could use a constructor, however:type we could use a constructor, however: this way we could not convert to fundamental type this way we could not convert to fundamental type

(like: int, it’s not a class), (like: int, it’s not a class), this way we could not convert to already defined this way we could not convert to already defined

class without redefining it.class without redefining it.

Page 38: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

ExampleExample

class counterclass counter{{ int cnt;int cnt; public:public: counter(int counter(int ii=0)=0):cnt(i){}:cnt(i){}; ; int operator()(int =1); int operator()(int =1); // increment by arg. or by 1// increment by arg. or by 1 operator int(); operator int(); // // convert toconvert to int int operator double(); operator double(); // // convert toconvert to doubledouble counter &operator+=(int); counter &operator+=(int); friend counter operator+(int, counter); friend counter operator+(int, counter); // int+counter// int+counter, friend, friend counter operator+(int); counter operator+(int); // counter+int// counter+int int operator++();int operator++(); // ++counter// ++counter int operator++(int);int operator++(int); // counter++// counter++};};

Page 39: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

ExampleExample

inline int counter::operator ()(int i)inline int counter::operator ()(int i){{ return cnt+=i;return cnt+=i;}}

inline counter::operator int()inline counter::operator int(){{ return cnt;return cnt;}}

inline counter::operator double()inline counter::operator double(){{ return double(cnt);return double(cnt);}}

Page 40: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

ExampleExample

counter & counter::operator +=(int i)counter & counter::operator +=(int i){{ cnt+=i; cnt+=i; // operator// operator()()((ii)); (*this)(i); (*this)(i)

return *this;return *this;}}

counter operator+(int i, counter l)counter operator+(int i, counter l){{ l+=i; l+=i; // // friend was not necessaryfriend was not necessary

return l;return l;}}

Page 41: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

ExampleExample

counter counter::operator +(int i)counter counter::operator +(int i){{ counter l=*this; counter l=*this; l+=i;l+=i; return l;return l;}}

int counter::operator ++()int counter::operator ++(){{ cnt+=1;cnt+=1; return cnt;return cnt;}}

int counter::operator ++(int)int counter::operator ++(int){{ int ret=cnt;int ret=cnt; cnt+=1;cnt+=1; return ret;return ret;}}

Page 42: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

ExampleExample

class complexclass complex{{ double re, im;double re, im;public: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 &);};};

Page 43: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

ExampleExample

complex & complex::operator = (const complex &c)complex & complex::operator = (const complex &c) {{ re=c.re;re=c.re; im=c.im;im=c.im;

return *this;return *this; }}

Page 44: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

ExampleExample

complex & complex::operator += (const complex &c)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)inline complex complex::operator + (const complex & c){{ return complex(re+c.re, im+c.im); return complex(re+c.re, im+c.im); // // complex(double, double)complex(double, double)}}

Page 45: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

ExampleExampleinline complex & operator-=(complex & c1, const complex & c2)inline complex & operator-=(complex & c1, const complex & c2) //friend//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) complex operator-(const complex & c1, const complex & c2) //friend//friend{{ complex c=c1; complex c=c1; c-=c2;c-=c2;

return c;return c;}}

Page 46: This, friend and operators. this exists in every non-static method exists in every non-static method a pointer to the oblect, for which the method was

ExampleExample

istream & operator >>(istream & s, complex & c)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)ostream &operator <<(ostream & s, const complex & c){{ s << c.re << c.im;s << c.re << c.im;

return s;return s;}}