//: C12:OverloadingUnaryOperators.cpp
// From Thinking in C++, 2nd Edition
// Available at http://www.BruceEckel.com
// (c) Bruce Eckel 2000
// Copyright notice in Copyright.txt
#include <iostream>
using namespace std;/* Non-member functions: */
/*In questa classe vengono definite della member function di tipo "friend" che implementano degli operatori che possono essere chiamati come funzioni esterna alla classe. Per esempio l'operatore "+" posso richiamarlo senza 'agganciarlo' ad un oggetto. Es: a.+ (sintassi errata); +a (sintassi esatta);*/
class Integer
{
long i;
Integer* This() { return this; }
public:
Integer(long ll = 0) : i(ll) {}
/* 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 have non-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: */
/*Di seguita vengono definiti i vari operatori.*/
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 before(a.i);
a.i++;
return before;}
/* 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 before(a.i);
a.i--;
return before;}
/* Show that the overloaded operators work: */
void f(Integer a)
{
+a;
-a;
~a;
Integer* ip = &a;
!a;
++a;
a++;
--a;
a--;}
/* Member functions (implicit "this"): */
class Byte
{
unsigned char b;
public:
Byte(unsigned char bb = 0) : b(bb) {}
/* 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--;}
int main()
{
Integer a;
f(a);
Byte b;
g(b);} ///:~