Last active
August 29, 2015 14:23
-
-
Save rsbowman/e788740b2883c179851f to your computer and use it in GitHub Desktop.
Simple Envelope/Letter Pattern
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <memory> | |
using namespace std; | |
class Real; | |
class Integer; | |
class Number { | |
friend Real; | |
friend Integer; | |
public: | |
Number() {} | |
virtual Number add(const Number &n) const; | |
virtual Number realAdd(const Number &) const; | |
virtual Number intAdd(const Number& n) const; | |
virtual void print() const; | |
static Number makeReal(float r); | |
static Number makeInt(int v); | |
protected: | |
unique_ptr<Number> rep; | |
}; | |
class Real : public Number { | |
friend Integer; | |
friend Number; | |
float val; | |
Real(float r) : val(r) {} | |
virtual Number add(const Number &n) const; | |
virtual Number realAdd(const Number &) const; | |
virtual Number intAdd(const Number& n) const; | |
virtual void print() const; | |
}; | |
class Integer : public Number { | |
friend Real; | |
friend Number; | |
int val; | |
Integer(int n) : val(n) {} | |
virtual Number add(const Number &n) const; | |
virtual Number realAdd(const Number &) const; | |
virtual Number intAdd(const Number& n) const; | |
virtual void print() const; | |
}; | |
Number Number::add(const Number& n) const { | |
return rep->add(n); | |
} | |
Number Number::realAdd(const Number& n) const { | |
return rep->realAdd(n); | |
} | |
Number Number::intAdd(const Number& n) const { | |
return rep->intAdd(n); | |
} | |
Number Number::makeReal(float f) { | |
Number n; | |
n.rep.reset(new Real(f)); | |
return n; | |
} | |
Number Number::makeInt(int v) { | |
Number n; | |
n.rep.reset(new Integer(v)); | |
return n; | |
} | |
void Number::print() const { | |
rep->print(); | |
} | |
Number Real::add(const Number& n) const { | |
return n.realAdd(*this); | |
} | |
Number Real::realAdd(const Number& n) const { | |
const Real *rn = dynamic_cast<const Real *>(&n); | |
return Number::makeReal(this->val + rn->val); | |
} | |
Number Real::intAdd(const Number& n) const { | |
const Integer *it = dynamic_cast<const Integer *>(&n); | |
return Number::makeReal(this->val+ it->val); | |
} | |
void Real::print() const { | |
cout << "R(" << val << ")"; | |
} | |
Number Integer::add(const Number& n) const { | |
return n.intAdd(*this); | |
} | |
Number Integer::intAdd(const Number& n) const { | |
const Integer *it = dynamic_cast<const Integer *>(&n); | |
return Number::makeInt(this->val+ it->val); | |
} | |
Number Integer::realAdd(const Number& n) const { | |
const Real *rn = dynamic_cast<const Real *>(&n); | |
return Number::makeReal(this->val + rn->val); | |
} | |
void Integer::print() const { | |
cout << "I(" << val << ")"; | |
} | |
void print_sum(Number& n1, Number& n2) { | |
n1.print(); cout << " + "; n2.print(); | |
cout << " = "; n1.add(n2).print(); | |
cout << endl; | |
} | |
int main(void) { | |
Number i1 = Number::makeInt(5); | |
Number i2 = Number::makeInt(11); | |
Number r1 = Number::makeReal(3.14); | |
Number r2 = Number::makeReal(0.5); | |
print_sum(i1, i2); | |
print_sum(i1, r1); | |
print_sum(r2, i1); | |
print_sum(r1, r2); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment