Reputation: 635
I need to use some constant value in a cpp
file which is related to a class and won't be used outside of it.
I came up with several methods of doing this:
static const
in a .cpp
filestatic const int a = 100; // <<<
int Class::foo() const
{
return a + 10;
}
int Class::bar() const
{
return a - 10;
}
If I get this right, I can also omit the static
keyword as the const
automatically implies the internal linking in this context.
Please, correct me if I'm wrong.
Basically same as the previous but:
namespace
{
const int a = 100;
}
I believe this method is the preferred way to declare such scoped constants over the previous one in C++11.
Again, correct me if I'm wrong.
static const
in a .h
fileclass Class
{
public:
int foo() const;
int bar() const;
protected:
static const int a = 100; // <<<
};
const
in .h
(C++11)class Class
{
public:
int foo() const;
int bar() const;
protected:
const int a = 100; // <<<
};
Or like this: const int a{100}
. I think there is no difference for POD types.
And once again, correct me if I'm wrong.
class Class
{
public:
Class() : a(100) {} // <<<
int foo() const;
int bar() const;
protected:
const int a;
};
I guess I must not use methods 1 and 2 as they will fail if I'll ever need to create a subclass.
Also, I think that the method 5 will be hard to maintain if there are many overloaded constructors.
Though the question may be considered opinion-based, mainly I'm trying to figure out the pros and cons of these methods, and probably there are some other possible solutions.
Upvotes: 4
Views: 1140
Reputation: 39818
For ordinary global variables, const
does imply static
(but note that const char *f;
isn’t const), so #1 with or without static
is indeed the same. (This is really a misfeature, included as an emulation of constexpr inline
many years before variables could have those.) #2 is also the same (preferred only in that types can also be declared in an anonymous namespace but cannot be declared static
).
These are not intrinsically bad for derived classes: they restrict the constant to a source file, which can define methods for as few or as many classes as you like. You can also put them in .hpp
files, although preferring a class member is reasonable.
For #3, note that the variable need not be initialized in the class definition. Doing so lets it be used in constant expressions in every file that includes the header, in which case the modern style (which supports non-integer variables) is to use constexpr
.
#4 and #5 add a member to every class object and are best avoided—consider that they disable the default assignment operators.
Upvotes: 3