Best approach for defining a constant (used in constant expression) in a class?

I am trying to define the BUFFER_LENGTH constant for my class for a given usecase.

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

I just listed various ways to define a constant for a class.

 1. Using Preprocessor constant 2. Using Global constant 3. Using in-class constant 4. using an enum. 

Of these, which is the best approach for determining constants for a given use case? I prefer to use the enumeration constant over other approaches. Is there any other better approach that I skipped.

Thanks,

+6
c ++ constants
source share
7 answers

The enumeration type is not intended to define a numerical constant, although it (ab) is used for this in the metaprogramming template.

If the constant value is confused with the class, I would define it there. Then you still have two options:

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

The positive side of the second choice is that you no longer need to change any client code when you want, for example, to read a constant from the registry or a configuration file.

+10
source share

For maintenance purposes, it is always best to limit the scope of any name (be it a function, variable or constant) as much as possible. Therefore, I would suggest either

 static const int BUFFER_LENGTH = 12; 

or

 enum { BUFFER_LENGTH = 12 }; 

inside the class definition.

In the first case, the advantage is not very strong, except that you can explicitly control the type. enum makes C ++ choose an undefined integral "base type" for you - it can be like a char if your enum contains only small values, although empirically most compilers will use int by default.

+9
source share

A static constant member variable is the best - it is concise, completely solves the problem and ensures that conflicts will not arise with other similar classes (which is quite possible using the definition of a preprocessor or global constant). I suggest you declare it in CamelCase, and in all capitals with undescores, so that it does not look like something special, but as a normal member of the class that it really is.

+3
source share

I read in C ++ Thinking that enum-hack was used in the past because some compilers did not support members of the static const class:
http://www.linuxtopia.org/online_books/programming_books/thinking_in_c++/Chapter08_023.html

So, if you use an antique compiler or want to support them, use enum-hack. (I have no idea how old they should be so as not to support the static const)

+2
source share

I am not sure that they are completely interchangeable in this particular case. Since you base the size of an array member on a constant, I believe that this should be an enumerated value. I do not have time to search in the standard, but I would be surprised if you could use the int member as the size of the array, even if it is static const , since the actual value may not appear in the header.

 // === 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; } 

I do not think that the compiler can compile otherclass.cpp without compiling myclass.cpp .

In most other cases, I would say Go with the parameter of the static constant of the class, since it will participate a little more reasonably in type inference and the like. I only use enumerated integer constants when I really need to or when they are really enumerated constants (of course).

Edit

I just looked at Standard while I was a goldfinch for lunch (thanks for pushing David).

An integer constant expression can include only literals (2.13), enumerations, const variables or static data elements to initialize integer or enumerated types with constant expressions (8.5), asymmetric integral template parameters, or enumeration types and sizeof expressions.

It seems that the constant and enumeration will work provided that you provide a constant initializer in the declaration (or is it a definition?).

+1
source share

Using const int may be less efficient than using enumeration, below is a program that demonstrates this. Compiled with Metrowerks CodeWarrior 8.x for Windows, it shows that a class object that defines a constant as const int takes 4 bytes of memory more than a similar class that defines this constant as an enumeration:

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

It produces: "4 8"

Constructors have been added to prevent aggressive optimization by the compiler. Because the program does not create objects of these types, constructors need not be defined in a separate compilation unit. The same is true for const int

+1
source share

While reading previous posts, I noticed that no one mentioned the trick "enum in the namespace". If you like the enumeration because you work with an older compiler (I had such experience on the VxWorks / Tornado built-in programming platform), then listen: you can avoid name collisions by putting enum in the namespace or (if the namespaces do not match the supported either) inside the class.

0
source share

All Articles