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?

4
  • 1
    that makes no sense. how exactly do you save compile time? 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. 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. Jun 29, 2017 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, 2017 at 18:26

1 Answer 1

12

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.

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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