// File from page 401 in "Thinking in C++" by Bruce Eckel ////////////////////////////////////////////////// // From the compressed package ECKELT02.ZIP 4/11/95 // (Original ECKELT01.ZIP dated 2/21/95) // Copyright (c) Bruce Eckel, 1995 // Source code file from the book "Thinking in C++", // Prentice Hall, 1995, ISBN: 0-13-917709-4 // All rights reserved EXCEPT as allowed by the following // statements: You may freely use this file for your own // work, including modifications and distribution in // executable form only. You may copy and distribute this // file, as long as it is only distributed in the complete // (compressed) package with the other files from this // book and you do not remove this copyright and notice. // You may not distribute modified versions of the source // code in this package. This package may be freely placed // on bulletin boards, internet nodes, shareware disks and // product vendor disks. You may not use this file in // printed media without the express permission of the // author. Bruce Eckel makes no // representation about the suitability of this software // for any purpose. It is provided "as is" without express // or implied warranty of any kind. The entire risk as to // the quality and performance of the software is with // you. Should the software prove defective, you assume // the cost of all necessary servicing, repair, or // correction. // If you think you've found an error, please // email all modified files with loudly commented changes // to: eckel@aol.com (please use the same // address for non-code errors found in the book). ////////////////////////////////////////////////// //: UNARY.CPP -- Overloading unary operators #include class integer { long i; integer* This() { return this; } public: integer(long I = 0) : i(I) {} // No side effects takes const& argument: friend const integer& operator+(const integer& a); friend const integer operator-(const integer& a); friend const integer operator~(const integer& a); friend integer* operator&(integer& a); friend int operator!(const integer& a); // Side effects don't take const& argument: // Prefix: friend const integer& operator++(integer& a); // Postfix: friend const integer operator++(integer& a, int); // Prefix: friend const integer& operator--(integer& a); // Postfix: friend const integer operator--(integer& a, int); }; // Global operators: const integer& operator+(const integer& a) { cout << "+integer\n"; return a; // Unary + has no effect } const integer operator-(const integer& a) { cout << "-integer\n"; return integer(-a.i); } const integer operator~(const integer& a) { cout << "~integer\n"; return integer(~a.i); } integer* operator&(integer& a) { cout << "&integer\n"; return a.This(); // &a is recursive! } int operator!(const integer& a) { cout << "!integer\n"; return !a.i; } // Prefix; return incremented value const integer& operator++(integer& a) { cout << "++integer\n"; a.i++; return a; } // Postfix; return the value before increment: const integer operator++(integer& a, int) { cout << "integer++\n"; integer r(a.i); a.i++; return r; } // Prefix; return decremented value const integer& operator--(integer& a) { cout << "--integer\n"; a.i--; return a; } // Postfix; return the value before decrement: const integer operator--(integer& a, int) { cout << "integer--\n"; integer r(a.i); a.i--; return r; } void f(integer a) { +a; -a; ~a; integer* ip = &a; !a; ++a; a++; --a; a--; } // Member operators (implicit "this"): class byte { unsigned char b; public: byte(unsigned char B = 0) : b(B) {} // No side effects: const member function: const byte& operator+() const { cout << "+byte\n"; return *this; } const byte operator-() const { cout << "-byte\n"; return byte(-b); } const byte operator~() const { cout << "~byte\n"; return byte(~b); } byte operator!() const { cout << "!byte\n"; return byte(!b); } byte* operator&() { cout << "&byte\n"; return this; } // Side effects: non-const member function: const byte& operator++() { // Prefix cout << "++byte\n"; b++; return *this; } const byte operator++(int) { // Postfix cout << "byte++\n"; byte before(b); b++; return before; } const byte& operator--() { // Prefix cout << "--byte\n"; --b; return *this; } const byte operator--(int) { // Postfix cout << "byte--\n"; byte before(b); --b; return before; } }; void g(byte b) { +b; -b; ~b; byte* bp = &b; !b; ++b; b++; --b; b--; } main() { integer a; f(a); byte b; g(b); }