Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

OpTemplate Class - A Demonstration of Operator Overloading

0.00/5 (No votes)
22 Aug 2002 1  
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

};

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here