繁体   English   中英

我应该在哪里放置班级需要的常量,以保持全局空间的自由?

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

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

分配

设计一个名为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" };

这部分的问题是,您将它们放在哪里?

有些事情我做不到...目前还不允许使用静态类成员,因为下一章将对此进行介绍。 我们也没有遍历指针,但是我们可以使用引用。

谢谢你的帮助!

我想请教官,但他不在城里,所以作业明天就要交。

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

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

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

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

您可以使用mynamespace::foousing namespace mynamespace;来访问此变量using 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或(对于非整数)类静态变量是最好的。 如果您的教授任意限制使用类静态变量,请将变量放在全局范围内(可能在名称空间中),并添加一条注释,说明如果允许的话,您将使它们成为类静态变量。

如果您不能执行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是更好的方法,但是由于这不是预期的用法,因此可能会造成混淆。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM