我正在为给定的用例为我的类定义一个常量BUFFER_LENGTH。
//1. Using preprocessor declaration
//#define BUFFER_LENGTH 12
//2.Global constant
//const int BUFFER_LENGTH = 12;
class MyRequest
{
public:
//3. Define an in-class constant
//static const int BUFFER_LENGTH = 12;
//4. Declare an enum constant
enum
{
BUFFER_LENGTH = 12
};
MyRequest()
{
strcpy(mBuffer, "TestString");
printf("Buffer: %s, BUFFER_LENGTH = %d",mBuffer, BUFFER_LENGTH);
}
private:
char mBuffer[BUFFER_LENGTH];
};
我刚刚列出了为类定义常量的不同方法。
1. Using Preprocessor constant
2. Using Global constant
3. Using in-class constant
4. using an enum.
其中,哪个是定义给定用例的常量的最佳方法?我更喜欢使用枚举常量而非其他方法。 还有其他更好的方法,我错过了。
谢谢,
答案 0 :(得分:10)
枚举类型并不意味着定义数字常量,尽管它在模板元编程中使用了很多(ab)。
如果常量的含义与类纠缠在一起,我会在那里定义它。那你还有两个选择:
class WithConst {
public:
// 1. as a const static member variable
static const int sc_nNumber = 100; // I can initialize here for
// integral-types only
// 2. as a static member function - possibly inlined.
static int sf_nNumber() { return 100; }
};
第二种选择的优势在于您以后不需要更改任何客户端代码。从注册表或配置文件中读取常量。
答案 1 :(得分:9)
出于维护目的,最好尽可能地限制任何名称的范围(无论是功能,变量还是常量)。所以我建议
static const int BUFFER_LENGTH = 12;
或
enum { BUFFER_LENGTH = 12 };
里面类定义。
前者没有太大的好处,除了你可以明确控制类型。 enum
导致C ++为您选择一个未指定的整数“底层类型” - 如果您的枚举仅包含小值,它可能会小到char
,但根据经验,大多数编译器默认使用{ {1}}。
答案 2 :(得分:3)
静态const成员变量是最好的 - 它简洁,完全解决了问题并保证不会与其他类似的类发生冲突(这对于预处理器定义或全局常量来说是非常可能的)。我建议你在CamelCase中声明它,而不是在所有带有不受欢迎的大写字母中,这样它看起来不像特别的东西,而是作为一个普通的类成员,它确实是。
答案 3 :(得分:2)
我在“Thinking in C ++”中读到过去使用过“enum-hack”,因为有些编译器不支持“static const”类成员:
http://www.linuxtopia.org/online_books/programming_books/thinking_in_c++/Chapter08_023.html
因此,如果您使用的是古老的编译器,或者想要支持它们,请使用enum-hack。 (我不知道他们现在必须不支持静态const)
答案 4 :(得分:1)
我不确定在这种特殊情况下它们是否完全可以互换。由于您将数组成员的大小基于常量,我相信它必须是枚举值。我没有时间在标准中查找,但如果您可以使用int
成员作为数组大小,即使它是static const
,我会感到惊讶,因为实际值可能不是在标题中可见。
// === in myclass.h
class MyClass {
public:
static const int MY_SIZE;
private:
int ary[MY_SIZE];
};
// === in myclass.cpp
/*static*/ const int MyClass::MY_SIZE = 10;
// === in otherclass.cpp
void OtherClass::operation(MyClass& obj) {
std::cout << "Sizeof(MyClass) = " << sizeof(obj) << std::endl;
}
我不认为编译器可以在没有编译otherclass.cpp
的情况下编译myclass.cpp
。
在大多数其他情况下,我会说使用类静态常量选项,因为它会更加智能地参与类型推导等。我只在真正需要时使用枚举整数常量,或者当它们是真正枚举的常量时(当然)。
我刚看完标准品,而我正在吃午饭(感谢大卫的推动)
整数常量表达式只能涉及文字(2.13),枚举器,
const
变量或初始化的整数或枚举类型的静态数据成员 用常量表达式(8.5),非类型模板参数的积分或 枚举类型和sizeof
表达式。
如果你在声明中提供常量初始化器(或者是那个定义?),看起来常量和枚举都可以工作。
答案 5 :(得分:1)
使用const int可能效率低于使用enum,下面是一个演示此内容的程序。使用Metrowerks CodeWarrior 8.x for Windows编译,它表明将类定义为const int的类的对象占用4个字节的内存,而不是将此常量定义为枚举的类似类:
#include <stdio.h>
#include <stdlib.h>
class foo {
enum { MY_CONST = 1 };
int x;
public:
foo();
};
class bar {
const int MY_CONST;
int x;
public:
bar();
};
int main() {
printf( "%u %u\n", sizeof( foo), sizeof( bar));
return EXIT_SUCCESS;
}
它产生:“4 8”
添加了构造函数以防止编译器进行积极的优化。因为程序不创建这些类型的对象,所以不必在单独的编译模块中实际定义构造函数。 const int
也是如此答案 6 :(得分:0)
在阅读之前的帖子时,我注意到没有人提到“命名空间中的枚举”技巧。如果您喜欢枚举,因为您正在使用较旧的编译器(我在VxWorks / Tornado嵌入式编程平台上有过这样的经验),那么请注意:您可以通过在命名空间中放置枚举或(如果命名空间不是命名空间)来避免命名冲突在一个班级内支持。