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

C++ 为了保持全局空间空闲,我应该在哪里放置类所需的常量?,c++,global-variables,C++,Global Variables,第一:我知道如何编写程序,所以我不是在寻求帮助。不过,我正在粘贴一份问题的副本,以便您可以看到作业所包含的内容。我的问题是专门针对你把变量放在哪里,以防止一切都全球化 作业 设计一个名为Date的类,该类具有整数数据成员来存储月、日和年。该类应该有一个三参数的默认构造函数,允许在创建新的日期对象时设置日期。如果用户创建日期对象时未传递任何参数,或者传递的任何值无效,则应使用默认值1、1、2001(即2001年1月1日)。该类应具有成员函数,以以下格式打印日期: 3/15/10 March 15,

第一:我知道如何编写程序,所以我不是在寻求帮助。不过,我正在粘贴一份问题的副本,以便您可以看到作业所包含的内容。我的问题是专门针对你把变量放在哪里,以防止一切都全球化

作业

设计一个名为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
(将用于
开关

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

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

谢谢你的帮助

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

1)你很难看<代码>静态常量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::foo
或使用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或(对于非整数)类静态将是最好的。如果您的教授任意限制类静态的使用,请将变量放在全局范围内(可能在命名空间中),并添加一条注释,说明如果允许,您将使它们成为类静态。

如果您不能执行
静态常量
成员(或局部变量),您可以将所有内容放在命名空间中:

声明:

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更好,但由于这不是预期用途,因此可能会造成混淆。

您可以将常量放在命名空间下。常量::我的常量;或者类似的东西。你可以使用静态局部变量吗?@Rob我知道静态成员,但直到第9章我才能使用它们。@FailedDev我想这可能也是最好的方法。不是静态成员,而是静态局部变量。请看我即将给出的答案。您介意提供一个如何实现静态局部变量的示例吗?你会把它们放在构造器里吗?还是在构造函数调用的成员函数中?或者一些完全不同的实现。@ephaitch:参见我答案中的示例2。变量
monthNames
是一个静态局部变量。oops。。我又看了一遍,意识到MonthToString是一个函数。谢谢谢谢你的详细解释!
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)
    {
    }
}