65.9K
CodeProject is changing. Read more.
Home

OpTemplate Class - A Demonstration of Operator Overloading

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.83/5 (5 votes)

Aug 23, 2002

viewsIcon

50860

downloadIcon

323

Demonstration of operator overloading.

Introduction

This is a very crude demonstration of operator overloading. It requires you to have a bit of knowledge on operator overloading before you can fully utilize this class. This class is useful for those who don't remember all the necessary ingredients for the overloading of each operator. It allows you to cut and paste the section of code that you want, and modify it to suit your needs.

The following listing shows both global operator overloading and class member operator overloading. If all the global functions are excluded, the Template class can be compiled. It is a working, although useless, class.

The comments "Reimplement" show those functions which require you to change the implementation before it can be used. Those which have "No change necessary" can be used straight without changing as they depend solely on those functions that need re-implementation unless you feel there is a need to change them to improve performance.

Nothing much more can be said about the listing. Any comments and improvements to the template are much welcome. Let's maintain this reference for all beginners together.

// Global functions: unary function @x
// (No change necessary if coupled
// with member overloaded operators)
template<class T> T operator+(T x) {return +x;}
template<class T> T operator-(T x) {return -x;}
template<class T> T operator*(T x) {return *x;}
template<class T> T operator&(T x) {return &x;}
template<class T> T operator!(T x) {return !x;}
template<class T> T operator~(T x) {return ~x;}
template<class T> T operator++(T x) {return ++x;}
template<class T> T operator--(T x) {return --x;}

// Global functions: unary functions x@
// (No change necessary if coupled with
// member overloaded operators)
template<class T> T operator++(T x, int) {return x++;}
template<class T> T operator--(T x, int) {return x--;}

// Global functions: binary functions
// (No change necessary if coupled
// with member overloaded operators)
template<class T> const T& operator+(const T& x, 
  const T& y) {T w(x); w += y; return w;}
template<class T> const T& operator-(const T& x, 
  const T& y) {T w(x); w -= y; return w;}
template<class T> const T& operator*(const T& x, 
  const T& y) {T w(x); w *= y; return w;}
template<class T> const T& operator/(const T& x, 
  const T& y) {T w(x); w /= y; return w;}
template<class T> const T& operator%(const T& x, 
  const T& y) {T w(x); w %= y; return w;}
template<class T> const T& operator^(const T& x, 
  const T& y) {T w(x); w ^= y; return w;}
template<class T> const T& operator&(const T& x, 
  const T& y) {T w(x); w &= y; return w;}
template<class T> const T& operator|(const T& x, 
  const T& y) {T w(x); w |= y; return w;}

// Global functions: binary functions

// Reimplement if not using member overloaded operators
template<class T> bool operator==(T x, T y) 
  const {return x == y;}
template<class T> bool operator< (T x, T y) 
  const {return x < y;}
  // Reimplement if not using member overloaded operators
template<class T> bool operator!=(T x, T y) 
  const {return !(x == y);} // No change necessary
template<class T> bool operator> (T x, T y) 
  const {return (y < x);} // No change necessary
template<class T> bool operator<=(T x, T y) 
  const {return !(y < x);} // No change necessary
template<class T> bool operator>=(T x, T y) 
  const {return !(x < y);} // No change necessary
template<class T> const T& operator<<(T x, T y)
  {return x << y;} // Reimplement
template<class T> const T& operator>>(T x, T y)
  {return x >> y;} // Reimplement
// Reimplement if not using member overloaded operators
template<class T> const T& operator&&(T x, T y)
  {return x && y;} 
// Reimplement if not using member overloaded operators
template<class T> const T& operator||(T x, T y)
  {return x || y;}
// Reimplement if not using member overloaded operators
template<class T> const T& operator,(T x, T y)
  {return x , y;}
template<class T> ostream& 
  operator<<(ostream& os, const T& x)
  {os << x; return (os);} // Reimplement
template<class T> istream& 
  operator>>(istream& is, T& x)
  {is >> x; return (is);} // Reimplement


template<class T>
class Template
{
public:
    // STL-like types
    typedef T            value_type;
    typedef T&           reference;
    typedef const T&     const_reference;
    typedef T*           pointer;
    typedef const T*     const_pointer;
    typedef T*           iterator;
    typedef const T*     const_iterator;
    typedef size_t       size_type;
    typedef ptrdiff_t    difference_type;

    // Return STL-like iterators
    iterator         begin()         {return this;}     
    const_iterator     begin() const    {return this;}
    iterator         end()         {return this;}       
    const_iterator     end() const     {return this;}
    size_type     size() const     {return size_;}

    Template(size_t size=0) : size_(size)
            {memberA = new value_type[size];}
    Template(const Template& y) {*this=y;}
    ~Template() {delete[] memberA;}


    // Unary operators
    const Template& operator+() const 
      {+member; return *this;} // Reimplement
    const Template& operator-() const 
      {~member + 1; return *this;} // Reimplement
    const Template& operator*() const 
      {member; return *this;} // Reimplement
    const Template& operator&() const 
      {&member; return *this;} // Reimplement
    const Template& operator~() const 
      {~member; return *this;} // 1's complement (Reimplement)
    const Template& operator!() const 
      {!member; return *this;} // Reimplement
    pointer operator->() {return memberA;} // Reimplement

    // Increment and decrement operators
    const Template& operator++()    
      {++member; return *this;} // Prefix (Reimplement)
    const Template& operator--() 
      {--member; return *this;} // Prefix (Reimplement)
    Template& operator++(int) 
      {Template w(*this); ++*this; return w;}
      // Postfix (No change necessary)
    Template& operator--(int) 
      {Template w(*this); ++*this; return w;}
      // Postfix (No change necessary)

    // Assignment operators
    const Template& operator=(const Template& y) // Reimplement
    {
        if (this != &y) // make sure not same object
        {
            member = y.member;
            size_ = y.size_;
            // free member variables' memory
            delete[] memberA;
            // get new memory for member variables
            memberA = new value_type[y.size_];
            // copy value for member variables from y
            memberA = y.memberA;
        }
        return *this; // return ref for multiple assignment
    }
    Template& operator+= (const Template& y) 
      {member += y.member; return *this;} // Reimplement
    Template& operator-= (const Template& y) 
      {member -= y.member; return *this;} // Reimplement
    Template& operator*= (const Template& y) 
      {member *= y.member; return *this;} // Reimplement
    Template& operator/= (const Template& y) 
      {member /= y.member; return *this;} // Reimplement
    Template& operator%= (const Template& y) 
      {member %= y.member; return *this;} // Reimplement
    Template& operator<<=(size_t y) 
      {member <<= y; return *this;} // Reimplement
    Template& operator>>=(size_t y) 
      {member >>= y; return *this;} // Reimplement
    Template& operator&= (const Template& y) 
      {member &= y.member; return *this;} // Reimplement
    Template& operator|= (const Template& y) 
      {member |= y.member; return *this;} // Reimplement
    Template& operator^= (const Template& y) 
      {member ^= y.member; return *this;} // Reimplement

    // Binary operators
    Template operator+(const Template& y) const
      {Template w(y); w += *this; return w;} 
      // Addition  (No change necessary)
    Template operator-(const Template& y) const
      {Template w(y); w -= *this; return w;} 
      // Subtraction  (No change necessary)
    Template operator*(const Template& y) const
      {Template w(y); w *= *this; return w;} 
      // Multiplication  (No change necessary)
    Template operator/(const Template& y) const
      {Template w(y); w /= *this; return w;} 
      // Division  (No change necessary)
    Template operator%(const Template& y) const
      {Template w(y); w %= *this; return w;} 
      // Modulo  (No change necessary)
    Template operator&(const Template& y) const
      {Template w(y); w &= *this; return w;} 
      // Binary And  (No change necessary)
    Template operator|(const Template& y) const
      {Template w(y); w |= *this; return w;} 
      // Binary Or  (No change necessary)
    Template operator^(const Template& y) const
      {Template w(y); w ^= *this; return w;} 
      // Binary Xor  (No change necessary)
    Template operator<<(size_t y) const
      {Template w(y); w <<= y; return w;}
      // Left shift (No change necessary)
    Template operator>>(size_t y) const 
      {Template w(y); w >>= y; return w;}
	  // Right shift (No change necessary)
	Template operator&&(const Template& y) const 
	  {Template w(y); member && y.member; return w;} 
	  // Reimplement
	Template operator||(const Template& y) const 
	  {Template w(y); member || y.member; return w;} 
	  // Reimplement
	Template operator,(const Template& y) const 
	  {Template w(y); member , y.member; return w;} 
	  // Reimplement

	// Comparison operators
	bool operator==(const Template& y) const 
	  {return (member == y.member);} // Reimplement
	bool operator< (const Template& y) const 
	  {return (member < y.member);}  // Reimplement
	bool operator!=(const Template& y) const 
	  {return !(*this == y);} // No change necessary
    bool operator> (const Template& y) const 
      {return (y < *this);} // No change necessary
    bool operator<=(const Template& y) const 
      {return !(y < *this);} // No change necessary
    bool operator>=(const Template& y) const 
      {return !(*this < y);} // No change necessary

    // Member access
    reference operator[](size_type index) 
      {return memberA[index];} // Reimplement
    const_reference operator[](size_type index) 
      const {return memberA[index];} // Reimplement

    // Streams
    friend ostream& operator<<(ostream& os, 
      const Template& y)
      {os << y.member; return os;} // Reimplement
    friend istream& operator>>(istream& is, 
      Template& y) {is >> y.member; return is;} 
      // Reimplement

    // Functor 
    const Template& operator()(Template& y) 
      {*this * y; *this / y; return *this;} // Reimplement

    // Misc
    Template& operator->*(Template& y) 
      {return *this;} // Reimplement

    // Memory management
    void* operator new(size_t size) 
      {return ::new Template;} // Reimplement
    void* operator new(size_t n, T extra) 
      {return ::new Template;} // Reimplement
    void* operator new[](size_t size) 
      {return ::new Template[size];} // Reimplement            
    void* operator new[](size_t index, T extra) 
      {return ::new Template[size];} // Reimplement
    void  operator delete(void *p) 
      {::delete reinterpret_cast<Template*>(p);}
      // Reimplement
    void  operator delete(void *p, size_t size) 
      {::delete reinterpret_cast<Template*>(p);}
      // Reimplement
    void  operator delete[](void *p) 
      {::delete[] reinterpret_cast<Template*>(p);}
      // Reimplement                          
    void  operator delete[](void *p, size_t size) 
      {::delete[] reinterpret_cast<Template*>(p);}
      // Reimplement
    void  operator delete[](void *p, T extra) 
      {::delete[] reinterpret_cast<Template*>(p);}
      // Reimplement
    
private:
    T member; // Reimplement
    T* memberA; // Reimplement
    size_t size_; // Reimplement
};