为了保持全局空间自由,我应该在哪里放置我的类所需的常量?

发布于 2024-12-12 04:28:28 字数 1333 浏览 0 评论 0原文

首先:我知道如何编写程序,所以我不会寻求帮助。不过,我粘贴了问题的副本,以便您可以了解作业的内容。我的问题专门针对您在哪里放置变量以防止一切都全球化?

赋值

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

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

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

感谢您的帮助!

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

First: I know how to write the program, so I'm not asking for help with that. However, I am pasting a copy of the problem so you can see what the assignment entails. My question is specifically aimed at where do you place variables to keep from making everything global?

Assignment

Design a class called Date that has integer data members to store month, day, and year. The class should have a three-parameter default constructor that allows the date to be set at the time a new Date object is created. If the user creates a Date object without passing any arguments, or if any of the values passed are invalid, the default values of 1, 1, 2001 (i.e., January 1, 2001) should be used. The class should have member functions to print the date in the following formats:

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

Questions

1) The teacher has instructed us to avoid using magic numbers in our code, so the first question is regarding my implementation of the default constructor:

// 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);

Is this correct?

2) The class needs access to an array of string objects which hold the month names so I can use them for date outputs which display the month name instead of the month number. I used an enum for the numeric month (which will be used for the 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" };

The question for this part, is where do you place them?

Some things I can't do...
I am not allowed to use static class members yet because that will be covered in the next chapter. We also have not gone over pointers, but we can use references.

Thanks for your help!

I would ask the instructor but he is out of town and the assignment is due tomorrow.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

╰◇生如夏花灿烂 2024-12-19 04:28:28

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) Defines are ugly. static const int members are what I would do, but you can't ... How about enums?

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) A static member array is just what you need. But since you can't ... maybe static local variables:

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]);
    }
};
廻憶裏菂餘溫 2024-12-19 04:28:28

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

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

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

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

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

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

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

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

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

但是,由于数组深深嵌入到您的实现中,因此它并不比“幻数”好多少。

就您而言,我确实认为使用枚举或(对于非整数)类静态是最好的。如果你的教授任意限制类静态的使用,请将变量放在全局范围内(可能在命名空间中),并添加一条注释,说明如果允许的话,你会将它们设为类静态。

If you would like to define a constant without polluting a global namespace, two of your best options are using namespaced globals or class statics. Since you say you can't use class statics, I'll show an example of namespaced globals:

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

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

You can access this variable as mynamespace::foo, or by using namespace mynamespace; (which is to be avoided in header files), or as just foo in any other function in the mynamespace namespace. Since it's only accessible by something requesting (or otherwise being aware of) the mynamespace namespace, it avoids polluting the global namespace (and all the unfortunate name collisions this involves).

For numeric values, an enum is another choice:

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

These values are compile-time constants; you cannot take the address of them (but they can be a bit faster than const variables). Note that this can only be used for integer values.

Function statics are another good option:

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

However, because the array is embedded deep into your implementation, it's not much better than a 'magic number'.

In your case, I do think either using enums or (for non-integers) class statics would be best. If your professor has arbitrarily restricted use of class statics, put the variables at global scope (possibly in a namespace) and add a comment stating that you would have made them class statics if you were allowed to.

雪若未夕 2024-12-19 04:28:28

如果你不能做 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,它们会污染< em>所有命名空间,并使调试变得更加棘手。枚举更好,但由于这不是预期的用法,因此可能会令人困惑。

If you can't do static const members (or locals) you can just put everything in a namespace:

declaration:

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

definition:

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)
    {
    }
}

Don't use DEFINEs, they pollute all namespaces, and make debugging trickier. enums are better, but since that's not the intended usage, it can be confusing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文