#includeusing namespace std; template<typename T> class Rectangle { private: T width; T height; public: Rectangle() : Rectangle(1, 1) { } Rectangle(T w, T h) : width(w), height(h) { } T getWidth() const { return width; } T getHeight() const { return height; } // binary - (as method): "this - rect2" (implicit first Rectangle) Rectangle<T> operator-(const Rectangle<T>& rect2) { T newWidth = this->getWidth() - rect2.getWidth(); T newHeight = this->getHeight() - rect2.getHeight(); Rectangle<T> result( newWidth, newHeight ); return result; } // unary - (as method): "-this" (implicit Rectangle), see below for implementation as standalone function Rectangle<T> operator-() { T newWidth = -this->width; T newHeight = -this->height; Rectangle<T> result( newWidth, newHeight ); return result; } // scale a rectangle by factor (as method): "this * scale" (implicit Rectangle) Rectangle<T> operator*( T scale ) { T newWidth = this->getWidth() * scale; T newHeight = this->getHeight() * scale; Rectangle<T> result( newWidth, newHeight ); return result; } // update a rectangle by another (as method): "this += rect2" (implicit first Rectangle) Rectangle<T>& operator+=(const Rectangle<T>& rect2) { width = width + rect2.getWidth(); height = height + rect2.getHeight(); return *this; } // update a rectangle by scaling it (as method): "this *= scale" (implicit Rectangle) Rectangle<T>& operator*=( int scale ) { this->width *= scale; this->height = this->height * scale; return *this; } }; // binary + (as function): "rect1 + rect2" (both Rectangles given explicitly) template<typename T> Rectangle<T> operator+(const Rectangle<T>& rect1, const Rectangle<T>& rect2) { T newWidth = rect1.getWidth() + rect2.getWidth(); T newHeight = rect1.getHeight() + rect2.getHeight(); Rectangle<T> result( newWidth, newHeight ); return result; } /* // unary - implemented as standalone function (Rectangle given explicitly) template<typename T> Rectangle<T> operator-(const Rectangle<T>& rect) { T newWidth = -rect.getWidth(); T newHeight = -rect.getHeight(); Rectangle<T> result( newWidth, newHeight ); return result; } */ // scale a rectangle by factor (as method): "scale * rect" (Rectangle given explicitly) template<typename T> Rectangle<T> operator*( int scale, const Rectangle<T>& rect ) { // uses the other version "rect * scale" which was implemented as method return rect*scale; } template<typename T> void print(const Rectangle<T>& rect) { cout << rect.getWidth() << ", " << rect.getHeight() << endl; } int main() { Rectangle rect_ushort( 10, 20 ); Rectangle rect_long( 50, 30 ); Rectangle rect_double( 10, 20 ); Rectangle r1( 10, 20 ); Rectangle r2( 50, 30 ); Rectangle r3 = r1 + r2; // i.e. operator+(rect1, rect2), add(r1, r2) r3 = -r1; // the unary - r3 = 2 * r1; // scale * rect r3 = r1 * 2; // rect * scale r3 *= 2; // double r3 r1 += r2; // enlarge r3 r1 += r2 += r3; // weird stuff r1 += r1 += r1; (r2 += r1) += r1; r3 = r2 = r1 += r1 += r1; print(r1); print(r2); print(r3); return 0; }