Skip to content

Instantly share code, notes, and snippets.

@MORTAL2000
Created December 21, 2015 20:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MORTAL2000/8010a770b011ef517997 to your computer and use it in GitHub Desktop.
Save MORTAL2000/8010a770b011ef517997 to your computer and use it in GitHub Desktop.
#include <iostream>
#include <exception>
class Money
{
public:
Money(float amount = 0);
// Money only has integer types. It doesn't manage any memory.
// So the default copy/move constructor/assignment and destructor all do the right thing.
// Let the compiler do its job
// if we need define them explicity, we can do as below
// c++0x
//Money(const Money& other) = default;
//Money(Money&& other) noexcept = default;
//~Money() = default;
//Money& operator=(Money const& other) = default;
//Money& operator=(Money&& other) = default;
// c++98 older
Money(const Money& other);
Money(Money&& other) noexcept;
~Money();
Money& operator=(const Money& other);
Money& operator=(Money&& other);
void swap(Money& other);
// logic operations
//a != b === !(a == b)
//a > b === b < a
//a >= b === !(a < b)
//a <= b === !(b < a)
bool operator<(const Money& other) const
{
return m_amount < other.m_amount;
}
bool operator>(const Money& other) const
{
return other < *this;
}
bool operator>=(const Money& other) const
{
return !(*this < other);
}
bool operator<=(const Money& other) const
{
return !(other < *this);
}
bool operator==(const Money& other) const
{
return m_amount == other.m_amount;;
}
bool operator!=(const Money& other) const
{
return !(*this == other);
}
// arithmetic operations
Money operator+=(const Money& other)
{
m_amount += other.m_amount;
return *this;
}
friend Money operator+(Money lhs, const Money& rhs)
{
return lhs += rhs;
}
Money operator-=( const Money& other)
{
m_amount -= other.m_amount;
return *this;
}
friend Money operator-(Money lhs, const Money& rhs)
{
return lhs -= rhs;
}
Money operator*=(const Money& other)
{
m_amount *= other.m_amount;
return *this;
}
friend Money operator*(Money lhs, const Money& rhs)
{
return lhs *= rhs;
}
Money operator/=(const Money& other)
{
if (other.m_amount == 0)
throw std::invalid_argument("Division by zero");
m_amount /= other.m_amount;
return *this;
}
friend Money operator/(Money lhs, const Money& rhs)
{
return lhs /= rhs;
}
friend std::ostream& operator<<(std::ostream& os, const Money& money);
private:
float m_amount;
};
Money::Money(float amount)
: m_amount(amount)
{
}
Money::Money(const Money& other)
: m_amount(other.m_amount)
{
}
// Move constructor should be a noexcept
// There are certain container operations that are more efficient if
// you make these noexcept because the container is trying to gurantee
// the strong exception gurantee. If your move constructor can throw
// the container must copy its members. If your constructor does not
// throw then it can use a move of the container internals.
//
// Also you can not pass by const here.
// You are stealing the content of the other object. This usually means
// you have to alter it (so it does not release any resources).
//Money::Money(const Money&& other) {
//
// Also because your class does not have a move
// assignment operator. This means it will default to copy
// *this = std::move(other);
//
// Also note that you don't initialize the members before you
// Try and do the move. This does not matter here because
// you have no resources. But since move is usally defined
// in terms of swap you would be swapping random values into
// the source location.
//}
// so orrect implementation is like this:
Money::Money(Money&& other) noexcept
: m_amount(std::move(other.m_amount))
{
}
Money::~Money()
{
}
Money& Money::operator=(const Money& other)
{
Money temp(other);
temp.swap(*this);
return *this;
}
Money& Money::operator=(Money&& other)
{
other.swap(*this);
return *this;
}
void Money::swap(Money& other)
{
using std::swap;
swap(m_amount, other.m_amount);
}
std::ostream& operator<<(std::ostream& os, const Money& money)
{
return os << '$' << money.m_amount;
}
int main()
{
Money your_money(1.70f);
Money my_money(1.30f);
Money his_money = std::move(your_money);
std::cout << your_money + my_money << '\n';
std::cout << your_money - my_money << '\n';
std::cout << std::endl;
std::cout << your_money << '\n';
std::cout << my_money << '\n';
std::cout << his_money << '\n';
std::cout << std::endl;
his_money = your_money - my_money;
if (my_money < your_money)
std::cout << "i'm poor (~.~) !\n";
if (my_money > his_money)
std::cout << "i'm rich ~~(^.^)~~ YEY!\n";
std::cout << (your_money = your_money * 1.7f) << '\n';
std::cout << (your_money = your_money / 1.7f) << '\n';
std::cout << (your_money *= 1.7f) << '\n';
std::cout << (your_money /= 1.7f) << '\n';
std::cout << (your_money * your_money) << '\n';
std::cout << (your_money / your_money) << '\n';
your_money = Money(1.7f);
std::cout << (your_money *= your_money) << '\n';
std::cout << (your_money /= your_money) << '\n';
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment