OpTemplate Class - A Demonstration of Operator Overloading






2.83/5 (5 votes)
Aug 23, 2002

50860

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 };