1 / 19

Operators

Operators. An operator is (just) a convenient way to write a function call. There is a fixed set of symbols that can be used as operators, like: + - * ! += < ... C++ allows the definition of operators for classes.

cana
Download Presentation

Operators

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Operators An operator is (just) a convenient way to write a function call. There is a fixed set of symbols that can be used as operators, like: + - * ! += < ... C++ allows the definition of operators for classes. But priorities (operator precedence) can not be changed: the bracketing of an expression never changes. A = B + C; A = sum( A, C ); add( A, B, C ); A * B + C & D == (( A * B ) + C ) & D

  2. Unary and Binary operators Unairy (monadic) operators (one argument): ++ -- & + - * Binary (diadic) operators (two arguments): = == += >= << + - & a++; b—; f( &c ); x = +d; y = -d; *p = *q; a = b; if( a == b ){ . . . } c += 5; while( a >= b ){ . . . } a = a << 2; a = a + b; a = a – b; a = a & 0x0F;

  3. Defining an operator Operator @ (if it existed) would be defined by the function operator@ (operator is a reserved word). int operator@( Clock c ){ return 42; } A monadic operator has one argument. const Clock operator+( Clock c ){ return c; } A diadic operator has two arguments. const Clock operator+( const & Clock c, const & Clock d ){ int s = c.readSec() + d.readSec(); int m = c.readMin() + d.readMin() + ( s / 60 ); int h = c.readHour() + d.readHour() + ( m / 60 ); return Clock( h % 24, m % 60, s % 60 ); }

  4. Defining a class operator Like other class functions, the first argument is implicit. But we still need a place to specify the lhs as const. class Clock { . . . Clock operator+( const & Clock d ) const; } A class operator has direct access to the attributes of the class, even inside the d parameter. But you don’t need to use direct access. (Why might it be wise not to?) Clock Clock::operator+( const & Clock d ) const { int ss = s + d.s; int mm = m + d.m + ( ss / 60 ); int hh = readHour() + d.readHour() + ( mm / 60 ); return Clock( hh % 24, mm % 60, ss % 60 ); }

  5. Using a class operator Operators can be called directly or indirectly. class Clock { const Clock operator+( const & Clock d ) const; } Clock c, d, e; c = d.operator+( e ); c = d + e; A class operator has direct access to the attributes of the class, even to the d parameter. But you don’t need to use direct access. (Why could it be wise not to?) Clock Clock::operator+( const & Clock d ) const { int ss = s + d.s; int mm = m + d.m + ( ss / 60 ); int hh = readHour() + d.readHour() + ( mm / 60 ); return Clock( hh % 24, mm % 60, ss % 60 ); }

  6. A monadic class operator A monadic class operator has zero arguments (why?). class Clock { const Clock operator+( void ) const; } const Clock Clock::operator+( void ) const { return *this; } Sometimes you have to refer to ‘yourself’.

  7. Don’t confuse the user Preserve the semantics of the existing operators. You can define operator+ to do multiplication... Class C . . . C a, b, c; // addition + assignment a = b + c; // assignment + assignment-addition a = b; a += c; There is no operator=. How do you define assignment?

  8. Cascaded assignments Preserve the possibility and meaning of cascaded assignments and assignment-operators. Class C . . . C a, b, c; a = b = c; // this means: a = ( b = c ); // should be same as: // b = c; // a = b; a += b + = c; // this means: a += ( b += c ); // should be same as: // b += c; // a += b;

  9. The return type of assignments What do the red words mean? So which ones do we want? const my_int & operator=( const my_int & rhs ) const; a = b; // should this be allowed to change b? ( a = b ) = c; // this should be possible

  10. The return type of assignments I can’t change my lhs??? I won’t change my rhs. X const my_int & operator=( const my_int & rhs ) const; // prevent this: ( a = b ) = c; So no need to make a copy of it. No need to make a new object.

  11. A vector class • Vector : like an array, but: • Size set when created (not at compilation). • Lower bound is set at creation. • Index range can be queried. • Acces is checked against the index range. • Vector operations: == != + += =

  12. A vector class – interface 1 class Vector { public: // Constructors. Vector ( int first_index = 1, int n = 0 ); Vector ( const Vector & v ); // Destructor ~Vector () { delete [] pVec; } // Public operations. int first ( void ) const { return i1; } int last ( void ) const { return i1 + num - 1; } int length ( void ) const { return num; } int read ( int index ) const; void change ( int index, int value ); . . .  private: // The internal representation of a vector. const int i1; // first index int * pVec; // pointer to array of integers int num; // number of elements };

  13. A vector class – interface 2 class Vector { public: . . . // Comparison operators bool operator==( const Vector & rhs ) const; bool operator!=( const Vector & rhs ) const { return !(*this == rhs); } // Assignment operators const Vector & operator= ( const Vector & rhs ); const Vector & operator+=( const Vector & rhs ); const Vector & operator+=( int n ); // Binary operators Vector operator+( const Vector & rhs ) const; Vector operator+( int n ) const; // Unary operators const Vector & operator+( void ); . . . }; What exactly does this mean? Lots of other operators could be defined, like: - ++ -- * / %

  14. A vector class – creators, access Vector::Vector( int first_index, int n ): i1( first_index ), num( n ) { assert( num >= 0 ); pVec = new int[ num ]; } Vector::Vector( const Vector & v ): i1( v.i1 ), num( v.num ) { pVec = new int [num]; for (int i = 0; i < num; i++){ pVec[i] = v.pVec[i]; } } int Vector::read (int index) const { assert (index >= i1 && index <= last ()); return pVec[index - i1]; } void Vector::change (int index, int val){ assert (index >= i1 && index <= last ()); pVec[index - i1] = val; } If possible, use initializers. Check and allocate. Allocate and copy. Why no check? Range checks.

  15. A vector class – equality, assignment bool Vector::operator== (const Vector & rhs) const { if (num != rhs.num){ return false;   } for (int i = 0; i < num; i++){ if (pVec[i] != rhs.pVec[i]){ return false; } } return true; } const Vector & Vector::operator= (const Vector & rhs){ if (this != &rhs){ delete [] pVec; num = rhs.num; pVec = new int [num]; for (int i = 0; i < num; i++){ pVec[i] = rhs.pVec[i]; } } return *this; } Different sizes can’t be equal. Why this check? Note something mising here? Result is lhs, or copy of lhs?

  16. A vector class – addition Can’t add different sizes. const Vector & Vector::operator+= (const Vector & rhs){ assert (num == rhs.num); for (int i = 0; i < num; i++){ pVec[i] += rhs.pVec[i]; } return *this; } const Vector & Vector::operator+= (int n){ for (int i = 0; i < num; i++){ pVec[i] += n; } return *this; } Vector Vector::operator+ (const Vector & rhs) const { Vector sum (*this); sum += rhs; return sum; } Why do we need a copy? What exactly happens here?

  17. Addition the wrong way Vector & Vector::operator+ (const Vector & rhs) const { Vector sum (*this); sum += rhs; return sum; } • One character added. • What difference does this one character make? • Why is this version wrong?

  18. A vector class – addition Vector Vector::operator+ (int n) const { Vector sum (*this); sum += n; return sum; } const Vector & Vector::operator+ (void){ return *this; }

More Related