我在哪里放置我班级所需的常量以保持全球空间免费?

时间:2011-10-27 19:07:59

标签: c++ global-variables

首先:我知道如何编写程序,所以我不是在寻求帮助。但是,我正在粘贴问题的副本,以便您可以看到分配所需的内容。我的问题是专门针对哪里放置变量以防止一切变得全局化?

分配

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

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 个答案:

答案 0 :(得分:4)

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]);
    }
};

答案 1 :(得分:2)

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

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

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

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

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

enum

这些值是编译时常量;你不能得到它们的地址(但它们可能比class foo { enum { CONST_FOO = 42, CONST_BAR = 24 }; }; 变量快一点)。请注意,这只能用于整数值。

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

const

但是,因为数组嵌入到您的实现中,所以它并不比“魔数”好多了。

在你的情况下,我确实认为使用void myclass::somefunction() { static const char *monthNames[] = { "JANUARY", ... }; //... } s或(对于非整数)类静态是最好的。如果您的教授任意限制使用类静态,请将变量放在全局范围内(可能在命名空间中)并添加注释,声明如果允许,您将使它们成为类静态。

答案 2 :(得分:0)

如果您不能成为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,它们会污染所有名称空间,并使调试更加棘手。 enum更好,但由于这不是预期用途,因此可能会造成混淆。