Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where to define class constants in C++?

In C++, to have a tidier code, I want to declare a set of values as constants in my header file, example :

constexpr float SIZE_SMALL = 1.5f; 
constexpr float SIZE_MEDIUM = 2.5f; 
constexpr std::string COLOR_RED = "RED"; 
constexpr std::string MATERIAL_SILK = "SILK";
...etc

But this is getting too long and clumsy. Also, some constants can be grouped together because they describe different values of the same property e.g. SIZE_SMALL and SIZE_MEDIUM.

What is the best way to write this in my header file? I thought about structs e.g.

struct SIZE
{
float SMALL; 
float MEDIUM; 
}

but then I have to declare and define a variable in my .cpp and that kinda beats the purpose of all this.

like image 414
Fakher Mokadem Avatar asked Dec 18 '22 14:12

Fakher Mokadem


2 Answers

then I have to declare and define a variable in my .cpp and that kinda beats the purpose of all this.

No you dont. You can make the fields static and constexpr :

struct SIZES {
    static constexpr const float SMALL = 1.5f;
};

However, I recommend to not do this. Not only you do not have to create an instance of this class, but also you should not create an instance of this class (what for?). So why use a class in the first place? Use namespaces instead to group constants:

namespace SIZES {
    constexpr float SMALL = 1.5f; 
}

I have some 50+ of these constants in the same name space

Unless you find a way to make the compiler read your mind, you have to write them all down somewhere. Serisously, the only way this could be condesned is if there is some relation between those constants, as eg SMALL + 1.0f = MEDIUM, but thats not apparent from your question.

like image 86
463035818_is_not_a_number Avatar answered Jan 02 '23 12:01

463035818_is_not_a_number


This depends on your actual usage but consider using proper strong types instead of basic types. For instance, to declare sizes, make them of type size, not float. This doesn’t directly solve your grouping problem but it gives you all of the other benefits of strong typing, and may also help with grouping:

struct size {
private: float value;
public:
    explicit constexpr size(float value) : value{value} {}
    explicit constexpr operator float() const noexcept { return value; }
};

namespace default_sizes {
    constexpr auto SMALL = size{1.5f};
    constexpr auto MEDIUM = size{2.5f};
    // …
}

In fact, for domain-specific usage, except in very limited cases, I’d generally avoid bare basic types and always encapsulate them in their own domain-specific type.

like image 40
Konrad Rudolph Avatar answered Jan 02 '23 10:01

Konrad Rudolph