8

Instead of using #define or const, I usually define constants using class static methods as follows:

//AppConstants.h
#include <string>
class AppConstants{
public:
 static int getMax();
 static std::string getPrefix();
};
//AppConstants.cpp
#include "AppConstants.h"
int AppConstants::getMax(){
 return 30;
}
std::string AppConstants::getPrefix(){
 return "myprefix";
}

I do this usually when creating a mobile app, which I would like to save the compile time when each time change the value for testing. Is it a bad practice?

asked Jun 29, 2017 at 7:28
4
  • 1
    that makes no sense. how exactly do you save compile time? Commented Jun 29, 2017 at 7:53
  • 2
    @BЈовић: When changing one of those constants, you only need to re-compile one file, instead of having to re-compile all files that reference one of the constants. Commented Jun 29, 2017 at 9:51
  • 1
    @BartvanIngenSchenau depends where you put the constant. If it is in the source file, then you do not need to recompile. Commented Jun 29, 2017 at 11:33
  • 3
    I don't know that what you are doing is bad practice, per-se. But I think calling them "constants" is bad practice. Specifically, getMax cannot be used as a case in a switch statement or to specify the size of an array. Therefore, getMax is not a "constant". Commented Jun 29, 2017 at 18:26

2 Answers 2

14

Yes, and it's unnecessary too. You can declare constants in headers and define them in source files just like functions:

class AppConstants {
public:
 static const int Max;
 static const std::string Prefix;
};
const int AppConstants::Max = 30;
const std::string AppConstants::Prefix = "myprefix";

Especially in the case of the string, this has the advantage of not constructing a new one every time you access it.

It also has the disadvantage of being affected by C++'s unspecified global initialization order, so be careful if you use the constants from the initialization of other global variables/constants.

answered Jun 29, 2017 at 7:54
6
  • 1
    While I mostly agree on this, why do you think it is a problem constructing a string every time? Commented Jun 29, 2017 at 8:17
  • 2
    It's an unnecessary heap allocation if the string is too long for SBO. Commented Jun 29, 2017 at 8:21
  • it should allocate only if you modify the string - not otherwise Commented Jun 29, 2017 at 8:23
  • 1
    Converting a string literal to a std::string allocates unless the std::string employs the Small Buffer Optimization and the string is short enough to fit. Copy-on-Write strings are not allowed in C++11, and CoW only applies to std::string's copy constructor anyway, not the one that takes a character pointer. Commented Jun 29, 2017 at 8:34
  • 6
    @Caleth operator""s is a convenient syntactical shortcut, but it doesn't magically get rid of the allocations. If you really want to avoid allocations, you have to use const std::string& getPrefix() { const static std::string prefix = "myprefix"; return prefix; } Commented Jun 29, 2017 at 8:36
1

That's a good question. I would add to other answers.

It's better to write it this way and use 'class' keyword for real classes only to be explicit about your intentions:

namespace AppConstants {
 static const int Max;
 static const std::string Prefix;
};

I think, that even this would work:

#pragma once
namespace AppConstants {
 const int Max;
 const std::string Prefix;
};

Those constants will be static by default. But I am not sure if the last variant is a good practice.

But the fact is, if you want to make your code as fast as possible, making extra function calls is not what you would usually want. And since you didn't add 'inline' keywords, it is very likely there will be some.

answered Oct 24, 2024 at 21:25

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.