2

For constants of a class, should I use class scope static const, or file scope const?

For example:

// .h
class C {
  private:
    static const int some_constant_c;
}

// .cc
const C::some_constant_c = 10;

vs.

// .h
class C {
}

// .cc
const some_constant_c = 10;

To me, the former one have better semantic meaning that the constant is of a certain class, but the latter one have the advantage not exposing constants to header file.

==============

One follow up question on this:

What if I want my constants be accessed by subclasses. Make sense to put static const in protected? Example follows:

// .h
class C {
  protected:
    static const int some_constant_c;
}
Luca
  • 322
  • 1
  • 13
  • Use object scope const. – user3528438 Apr 16 '15 at 19:37
  • You should read this answer: http://stackoverflow.com/a/3709257/4793675 –  Apr 16 '15 at 19:38
  • @user3528438 Care to share more? – Luca Apr 16 '15 at 19:43
  • Non-static const is object scope. It can be initialized to different values for different instances of the class in the constructor's initializer list. – user3528438 Apr 16 '15 at 19:45
  • @Ricardo Thanks for pointing to me this answer, which I did read. However, I'm struggling between `static const` in class declaration or source file. – Luca Apr 16 '15 at 19:45
  • @user3528438 I'm not struggling between class scope or object scope `const`, but `static const` in class declaration or source file. Note that `const` in source file is indeed `static const` in c++. – Luca Apr 16 '15 at 19:47
  • Follow-Up question: yes, in this case it should be the member of the class. There is no other (obvious/simple/not IOCCC) way to expose the constants to derived classes only. – Valentin H Apr 17 '15 at 06:10

2 Answers2

4

It's a matter of personal preference, of course. Trying not to expose class internals in the header file is a ship that has most definitely sailed in C++... between member variables and private member functions, it's just not practical to keep implementation details out of the header (unless you're using the pImpl idiom).

If all you want is to hide the value of the constant, note that you can put the initializer in the source file instead.

If you do implement the constants as globals in the source file, use an anonymous namespace to keep them from causing linker collisions.

Sneftel
  • 40,271
  • 12
  • 71
  • 104
  • " use an anonymous namespace to keep them from causing linker collisions." - If they are defined in .cc as in the question, they won't cause linker collision. – Valentin H Apr 16 '15 at 19:56
  • "If all you want is to hide the value of the constant, note that you can put the initializer in the source file instead." - It is actually what he did :-) – Valentin H Apr 16 '15 at 20:00
  • Thanks for your awesome answer! Mind to have a look at my follow up question? – Luca Apr 16 '15 at 22:33
2

I'd prefer 2nd variant, provided the const in the 1st case is private.

Why should one pollute the class declaration with redundant information? Consider, you are implementing a protocol parser, with many many constants. How will the class declaration look like?

Another issue is, why should you type the name of the const twice? I try to keep definition and initialization as close as possible.

Just an opinion.

Valentin H
  • 7,240
  • 12
  • 61
  • 111