Где я могу разместить константы, необходимые моему классу, чтобы освободить глобальное пространство? - PullRequest
5 голосов
/ 27 октября 2011

Во-первых: я знаю, как написать программу, поэтому я не прошу помощи с этим.Однако я вставляю копию проблемы, чтобы вы могли видеть, что влечет за собой назначение.Мой вопрос специально нацелен на то, где вы размещаете переменные, чтобы не делать все глобальным?

Назначение

Разработка класса с именем Date, который содержит целочисленные элементы данных для хранения месяца, день и год.Класс должен иметь трехпараметрический конструктор по умолчанию, который позволяет устанавливать дату в момент создания нового объекта Date.Если пользователь создает объект Date без передачи каких-либо аргументов или если любое из переданных значений недопустимо, следует использовать значения по умолчанию 1, 1, 2001 (т. Е. 1 января 2001 г.).В классе должны быть функции-члены для печати даты в следующих форматах:

3/15/10
March 15, 2010
15 March 2010

Вопросы

1) Учитель дал нам указание избегать использования магических чисел внаш код, поэтому первый вопрос касается моей реализации конструктора по умолчанию:

// These are outside the class.
#define DEFAULT_MONTH 1
#define DEFAULT_DAY   1
#define DEFAULT_YEAR  2001

// This is inside the class definition.
Date(int month = DEFAULT_MONTH, int day = DEFAULT_DAY, int year = DEFAULT_YEAR);

Это правильно?

2) Классу необходим доступ к массиву string объектов, которыеудерживайте названия месяцев, чтобы я мог использовать их для вывода даты, в котором вместо номера месяца отображается название месяца.Я использовал enum для числового месяца (который будет использоваться для switch).

const enum MONTH_IDS { JANUARY = 1, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY,
    AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER };

const string MONTH_NAMES[NUM_MONTHS] = { "January", "February", "March",
    "April", "May", "June", "July", "August", "September", "October",
    "November", "December" };

Вопрос к этой части, где вы их размещаете?

Некоторые вещи, которые я не могу сделать ... Мне запрещено использовать статические члены класса, потому что это будет рассмотрено в следующей главе.Мы также не перебрали указатели, но мы можем использовать ссылки.

Спасибо за вашу помощь!

Я бы попросил инструктора, но его нет в городе, и задание назначенозавтра.

Ответы [ 3 ]

4 голосов
/ 27 октября 2011

1) Определяет безобразно. static const int участники - это то, что я бы сделал, но вы не можете ... Как насчет перечислений?

struct Date {
    enum Constants {
        DEFAULT_YEAR = 2001,
        DEFAULT_MONTH = 1,
        DEFAULT_DAY = 1,
    };


    Date(int month = DEFAULT_MONTH, int day = DEFAULT_DAY, int year = DEFAULT_YEAR);

};

2) Статический массив-член - это то, что вам нужно. Но так как вы не можете ... возможно, статические локальные переменные:

struct Date {
    std::string MonthToString(enum MONTH_IDS m) {
        static const char *monthNames[] = {
            "January", "February", "March", "April", "May", "June",
            "July", "August", "September", "October", "November", "December" };
        if(m >= sizeof(monthNames)/sizeof(monthNames[0]))
            return std::string("Unknown");
        return std::string(monthNames[m]);
    }
};
2 голосов
/ 27 октября 2011

Если вы хотите определить константу, не загрязняя глобальное пространство имен, два из ваших лучших вариантов - использование глобальных пространств имен или статических классов. Поскольку вы говорите, что не можете использовать статические классы, я покажу пример глобальных пространств с именами:

// .h file
namespace mynamespace {
    extern const int foo;
};

// later, in a .cpp file
namespace mynamespace {
    const int foo = 42;
};

Вы можете получить доступ к этой переменной как mynamespace::foo, или using namespace mynamespace; (чего следует избегать в заголовочных файлах), или просто как foo в любой другой функции в пространстве имен mynamespace. Поскольку он доступен только тем, кто запрашивает (или иным образом знает) пространство имен mynamespace, он избегает загрязнения глобального пространства имен (и всех связанных с этим неудачных конфликтов имен).

Для числовых значений enum - это другой выбор:

class foo {
  enum { CONST_FOO = 42, CONST_BAR = 24 };
};

Эти значения являются константами времени компиляции; вы не можете взять их адрес (но они могут быть немного быстрее, чем const переменные). Обратите внимание, что это можно использовать только для целочисленных значений.

Функция статики - еще один хороший вариант:

void myclass::somefunction() {
    static const char *monthNames[] = { "JANUARY", ... };
    //...
}

Однако, поскольку массив встроен глубоко в вашу реализацию, он не намного лучше, чем «магическое число».

В вашем случае, я думаю, что лучше было бы использовать enum s или (для нецелых) статические классы. Если ваш профессор произвольно ограничил использование статических классов, поместите переменные в глобальную область видимости (возможно, в пространство имен) и добавьте комментарий о том, что вы бы сделали их статическими классами, если бы вам было позволено.

0 голосов
/ 27 октября 2011

Если вы не можете сделать static const участников (или местных), вы можете просто поместить все в пространство имен:

объявление:

namespace ephaitch {
    extern const int Date_default_month;
    extern const int Date_default_day;
    extern const int Date_default_year;
    class Date {
        Date(int month = DEFAULT_MONTH, int day = DEFAULT_DAY, int year = DEFAULT_YEAR);
    };
}

определение:

namespace ephaitch {
    const int Date_default_month = 1;
    const int Date_default_day = 1;
    const int Date_default_year = 2001; 

    enum MONTH_IDS { JANUARY = 1, FEBRUARY, MARCH, APRIL, 
                     MAY, JUNE, JULY, AUGUST, 
                     SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER 
                   };

    const string MONTH_NAMES[NUM_MONTHS] = { 
         "January", "February", "March",
         "April", "May", "June", 
         "July", "August", "September", 
         "October", "November", "December" 
        };

    Date(int month, int day, int year)
    {
    }
}

Не используйте DEFINE s, они загрязняют все пространства имен и усложняют отладку.enum лучше, но поскольку это не предполагаемое использование, это может сбить с толку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...