我在哪里放置类所需的常量,以保持全局空间自由

Where do I place constants needed by my class in order to keep global space free?

本文关键字:全局 自由 空间 常量 在哪里      更新时间:2023-10-16

第一:我知道如何编写程序,所以我不是在寻求帮助。不过,我粘贴了一份问题的副本,这样你们就能看到作业的内容了。我的问题是专门针对你在哪里放置变量,以防止使一切全局?

任务

设计一个名为Date的类,该类具有用于存储月、日和年的整数数据成员。该类应该有一个包含三个参数的默认构造函数,允许在创建新的date对象时设置日期。如果用户创建了一个Date对象而没有传递任何参数,或者传递的任何值都是无效的,则应该使用默认值1,1,2001(即2001年1月1日)。该类应该具有以下列格式打印日期的成员函数:

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

老师已经告诉我们要避免在代码中使用幻数,所以第一个问题是关于我的默认构造函数的实现:
// 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" };

这个部分的问题是,你把它们放在哪里?

有些事我做不到我还不允许使用静态类成员,因为这将在下一章中讨论。我们也没有讨论指针,但是我们可以使用引用。

谢谢你的帮助!

我想问一下老师,但他不在城里,作业明天就要交了

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);
};
静态成员数组正是你所需要的。但是既然你不能……也许是静态局部变量:
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]);
    }
};

如果您想在不污染全局命名空间的情况下定义常量,最好的两个选择是使用命名空间的全局变量或类静态。既然您说不能使用类静态,那么我将展示一个命名空间全局变量的示例:

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

您可以通过mynamespace::foousing namespace mynamespace;(在头文件中要避免使用)访问该变量,或者在mynamespace名称空间中的任何其他函数中仅作为foo访问该变量。由于它只能通过请求(或以其他方式意识到)mynamespace名称空间来访问,因此它避免了污染全局名称空间(以及由此涉及的所有不幸的名称冲突)。

对于数值,enum是另一种选择:

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

这些值是编译时常量;您不能获取它们的地址(但它们可能比const变量快一点)。注意,这只能用于整数值。

函数静态是另一个不错的选择:

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

然而,由于数组被嵌入到你的实现中,它并不比一个"幻数"好多少。

在你的情况下,我认为使用enum s或(非整数)类静态将是最好的。如果您的教授任意限制类静态的使用,请将变量置于全局作用域中(可能在名称空间中),并添加注释,说明如果允许,您将使它们成为类静态。

如果你不能做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 s更好,但由于这不是预期的用法,它可能会令人困惑。