How to restrict a class / structure so that only certain predefined objects exist?

Suppose your program should track, say, the months of the year. Each month has a name and length in days. Obviously, this is the information that you want to determine at compile time, and you want to limit your program so that no other information for the month is determined at run time. And, of course, you want to easily access month data without complex method calls. Typical examples of using this information would be free in the following 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;

While things that should not fly include:

Month m = Month("Jabruapril", 42);  // should give compiler error

Month m = MonthService().getInstance().getMonthByName("February");  // screw this

( , , , - .)

? , .

+3
5

- :

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);
...
+5

, . Singleton, , . private, .

class Month {
  public:
    static const Month JANUARY(...);
    ...
    static const Month DECEMBER(...);

    // public API
private:
  Month(...);

    // private members
};

const Month Month::JANUARY = Month(...);
...
const Month Month::DECEMBER = Month(...);
+1

Month private getMonth.

, Month singleton! , , .

-

Edit:

. Months , :

class Month
{
public:
    string name;
    int num_days;
public:
    static const Month JANUARY;
    static const Month FEBRUARY;
private:
    Month(string n, int nd) : name(n), num_days(nd) {}
};

const Month Month::JANUARY = Month("January", 31);
const Month Month::FEBRUARY = Month("February", 28);
+1

, :

1) Month - , 12 , 12 . ++ , :

  • (, , , /). Singleton.

  • , , . .

, Singleton (12-) . , " ", Month m = GetRandomMonth();, Month m. , , . , , .

Month , , , . , Twelveleton ( , 12 ), , 12 , . char - 256 ( ), 256 : char x[257] = {0};.

2) Month - , . 12 , (13, ), Month("Jabruapril", 42) () Month("Nisan", 30) ( ) Month("December", 30) ( ), , , , . , , .

(1) (2) .

Month , , (2), , . ( ), , , . , , , , . , (1), , , - .

Month , , , , - , (2) - - - . , , , .

+1

:

class Month
{
public:
    string name;
    int num_days;
private:
    Month(string n, int nd) : name(n), num_days(nd) {}
    friend class Months;
};

class Months
{
public:
    static const Month JANUARY;
    static const Month FEBRUARY;
    // ...
private:
    Months() {}
};

const Month Months::JANUARY = Month("January", 31);
const Month Months::FEBRUARY = Month("February", 28);
// ...

bool operator==(const Month& lhs, const Month& rhs)
{
    return lhs.name == rhs.name;
}

int main()
{
    cout << Months::JANUARY.name << " " << Months::JANUARY.num_days << endl;
    Month m = Months::FEBRUARY;
    if ( m == Months::FEBRUARY )
        cout << m.name << " " << m.num_days << endl;
    return 0;
}

, , , . , , Month .

0

Source: https://habr.com/ru/post/1793221/


All Articles