Suppose your program needs to keep track of, say, months of the year. Each month has a name and a length in days. Obviously, this is information that you want to define at compile time, and you want to limit your program so that no other month information can be defined during runtime. And of course you want to conveniently access month data without complicated method calls. The typical use cases for this information would loosely be along these lines:
Month m = GetRandomMonth();
if ( m == FEBRUARY )
CreateAppointment(2011, m, 28);
// Iterating over all months would be optional, but a nice bonus
for (/* each month m*/)
cout << "Month " << m.name << " has " << m.num_days << " days." << endl;
Whereas things that shouldn't fly include:
Month m = Month("Jabruapril", 42); // should give compiler error
Month m = MonthService().getInstance().getMonthByName("February"); // screw this
(I deliberately made the code as vague as possible to signify that I'm not limited to any particular implementation approach.)
What's the most elegant way of solving this problem? I'm adding my own aswer for public review, but other solutions are welcome.
How about something like:
class Month
{
public:
static const Month JANUARY;
static const Month FEBRUARY;
...
private:
Month(const std::string &name, int days) : name(name), days(days) {}
const std::string name;
const int days;
};
const Month Month::JANUARY = Month("January", 31);
const Month Month::FEBRUARY = Month("February", 28);
...