Created
December 21, 2015 20:44
-
-
Save MORTAL2000/8010a770b011ef517997 to your computer and use it in GitHub Desktop.
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 <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