0
votes

I made a super simple design to start solving a problem.

enter image description here

Now, this might seem like super trivial at first, but since there are tons of ways to do this, it confuses me, due to my lack of professional experience.

Where would I define those compile time constants? (Always suppose I'm using the highest current C++ standard version)

In a namespace? Inside the class? In a .h outside the class? In the .cpp outside the class? Just use them as magic numbers and add some comment? static? non-static? const? constexpr? template the deck size in case its bigger?

What I thought of:

class JolloManager
{
private:
    constexpr static int rounds = 3;
    constexpr static int deckSize = 52;
    constexpr static int princeId = 1;
    constexpr static int princessId = 2;
    std::array<int, deckSize> deck;
public:
    JolloManager() {};
};

Is this correct?

1
It depends on how and where they're used. Almost any of those solutions is OK except for the "magic numbers" one. - 1201ProgramAlarm
I really wish Bathsheba didn't delete his comment, if a programmer (with his amount of rep) said something about anonymous namespace then he probably meant something - snoopy
Note that "In a namespace? Inside a class?" is orthogonal to "In a .h outside the class? In the .cpp outside the class?". Choosing either of the first two does not help you choose from the second two. The first is about the logical location of the definitions; the second is about their physical location. - Pete Becker
@ViníciusMagalhãesHorta: I deleted the comment since deck needs to know about deskSize due to your using std::array. If you were able to switch to std::vector then you could use an anonymous namespace in the source file implementing JolloManager (assuming there's only 1). At least then you're not polluting the header file. - Bathsheba
Hi OP, do you have C++17 support? The question of how to define constants in C++ has, unfortunately, a rich history due to limitations of earlier standards. - Brian Bi

1 Answers

2
votes

In C++17, defining compile-time integer constants is easy.

First, you should decide whether or not the constant should be scoped to a class. If it makes sense to have it as a class member (e.g., it pertains to the concept that the class represents) then make it a class member. Otherwise, don't.

As a class member, write:

class JolloManager {
    constexpr static int rounds = 3;
};

That's it. No out-of-line definition is required anymore in C++17.

If it's not going to be a class member, but you want everyone who includes your header to be able to access the value, then write this in the header:

inline constexpr int rounds = 3;

(Technically, the reason to use inline is to avoid ODR violations when the variable is ODR-used by an inline function in multiple translation units.)

If the value is an implementation detail that only one .cpp file needs access to, then write the following in that .cpp file to give it internal linkage (i.e., prevent clashing with names in other translation units):

constexpr int rounds = 3;  // no `inline` this time

Finally, if the constant is only needed by a single function, you can make it local to that function:

void foo() {
    constexpr int rounds = 3;
}