6

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?

  • 1
    that makes no sense. how exactly do you save compile time? – BЈовић Jun 29 '17 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. – Bart van Ingen Schenau Jun 29 '17 at 9:51
  • @BartvanIngenSchenau depends where you put the constant. If it is in the source file, then you do not need to recompile. – BЈовић Jun 29 '17 at 11:33
  • 1
    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". – OldFart Jun 29 '17 at 18:26
11

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.

  • 1
    While I mostly agree on this, why do you think it is a problem constructing a string every time? – BЈовић Jun 29 '17 at 8:17
  • 2
    It's an unnecessary heap allocation if the string is too long for SBO. – Sebastian Redl Jun 29 '17 at 8:21
  • it should allocate only if you modify the string - not otherwise – BЈовић Jun 29 '17 at 8:23
  • 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. – Sebastian Redl Jun 29 '17 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; } – Sebastian Redl Jun 29 '17 at 8:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.