You have chosen the "non-inline" mode of initializing your static member. That is perfectly legitimate, but - in this case, you need to have exactly one translation unit (e.g. compiled .cpp
file) defining your member. Otherwise, the C++ linker sees one definition of Foo::A
in parent.o
and a second definition in child.o
, and those conflict.
Thus,
Solution 1: Move the definition to another file
- Create a
Foo.cpp
, which includes Foo.hpp
and defines Foo::A
.
- Delete the definition from the header, so it isn't repeated in multiple locations
Solution 2: Make the definition conditional
This is not really recommended, but it does work.
Surround the definition like so:
#ifdef FOO_A_DEFINITION
const int Foo::A = 100;
#endif
Create a Foo.cpp
, which defines #FOO_A_DEFINITION
and then includes Foo.hpp
This has the detriment of using macros, but the benefit of human users seeing the definition from the header.
Solution 3: Initialize in class definition
So, you are asking yourself "Why should they conflict? I want the compiler to know that they're the same variable!"
One way to do this to initialize the static member within the class body. Since this is a simple type, that's possible even with older versions of the language standard. This is also @idmean's suggested solution:
class Foo {
public:
static const int A = 100;
};
There's a caveat here, which is that you're "not really" defining the static member this way. You can use it, but not in every way you would use a variable defined with solutions (1.) or (2.). See discussion here:
See a discussion of this point here:
Defining static const integer members in class definition
Solution 4: Inline your static member
This solution is another way to tell the compiler "it's just one definition for everybody", which only works in C++17 or later:
#include <iostream>
class Foo {
public:
inline static const int A = 100;
};
This looks very similar to Solution 3, but actually does something very different!
With this solution, you're actually defining the static member multiple times - in each translation unit - but are telling the compiler to only keep a single definition when linking and encountering many of them.
Solutions (1.) and (2.) behave differently from this solution (4.) when you use dynamically-linked libraries. See:
Where to initialize static const member in c++17 or newer?
for an explanation.