patterncppModerate
Type-safe Date class with total encapsulation
Viewed 0 times
totalwithencapsulationdatetypesafeclass
Problem
I want to teach about "encapsulation" and chose
Disregarding if it's good to go to this extreme when encapsulating, does anyone have any comments about my demonstration code?
Intro section
Helper value classes
Helper value class
Helper value class
Helper value class
```
class Day {
int value_; // 1..31
public:
// v may be invalid day-of-month, to be normalized later, but >0 .
explicit Day(int v) : value_{v} {}
Day& operator+=(const Day& other) {
value_ += other.value_;
return *this
Date with Year, Month and Day as an example -- because it demonstrates type-safety w.r.t. preventing accidental swapping of parameters. I want to demonstrate encapusulation to the extreme, meaning I want to hide the int-values of the Year, Month and Day completely and instead define the operations in them as required.Disregarding if it's good to go to this extreme when encapsulating, does anyone have any comments about my demonstration code?
Intro section
// #!cpp filename=33a-dateplus.cpp
#include
#include
using std::ostream; using std::setfill; using std::setw;Helper value classes
Helper value class
Yearclass Year {
int value_; // eg. 2014
public:
explicit Year(int v) : value_{v} {}
Year& operator+=(const Year& other) {
value_ += other.value_;
return *this;
}
friend ostream& operator<<(ostream& os, const Year&x) {
return os << setfill('0') << setw(4) << x.value_;
}
bool isLeap() const;
};Helper value class
Monthclass Day;
class Month {
int value_; // 1..12
public:
// v may be invalid month-number, to be normalized later, but >0 .
explicit Month(int v) : value_{v} {}
Month& operator+=(const Month& other) {
value_ += other.value_;
return *this;
}
friend ostream& operator<<(ostream& os, const Month&x) {
return os << setfill('0') << setw(2) << x.value_;
}
void normalize(Year &year);
// precond: month must be normalized; value_ in [1..12]
Day days(const Year& inYear) const;
friend bool operator<(const Month &l, const Month& r) {
return l.value_ < r.value_;
}
};Helper value class
Day```
class Day {
int value_; // 1..31
public:
// v may be invalid day-of-month, to be normalized later, but >0 .
explicit Day(int v) : value_{v} {}
Day& operator+=(const Day& other) {
value_ += other.value_;
return *this
Solution
I have recently earned my M.Sc. in Comp.Sci. and one of the things that was my main gripes with any examples given to use during programming classes was the lack of consistency. So I'll say this, please be consistent and if you implement one arithmetic or relational operator you need to implement all of them that make sense.
And show them how to implement arithmetic and relational operators properly, some thing like this:
And show them how to implement arithmetic and relational operators properly, some thing like this:
T operatpr -() const{
T(*this) t;
...
return t;
}
T operator += (const T& rhs){
...
return *this;
}
T operator + (const T& rhs) const{
return T(*this) += rhs;
}
T operator -= (const T& rhs){
return *this += (-rhs);
}
T operator - (const T& rhs) const{
return *this + (-rhs);
}
bool operator (const T& rhs) const{
return rhs rhs);
}
bool operator >= (const T& rhs) const{
return !(*this < rhs);
}Code Snippets
T operatpr -() const{
T(*this) t;
...
return t;
}
T operator += (const T& rhs){
...
return *this;
}
T operator + (const T& rhs) const{
return T(*this) += rhs;
}
T operator -= (const T& rhs){
return *this += (-rhs);
}
T operator - (const T& rhs) const{
return *this + (-rhs);
}
bool operator < (const T& rhs) const{
return ...;
}
bool operator > (const T& rhs) const{
return rhs < *this;
}
bool operator <= (const T& rhs) const{
return !(*this > rhs);
}
bool operator >= (const T& rhs) const{
return !(*this < rhs);
}Context
StackExchange Code Review Q#44505, answer score: 11
Revisions (0)
No revisions yet.