Given is a class with a static member.
class BaseClass
{
public:
static std::string bstring;
};
String has obviously to be default-initialized outside of the class.
std::string BaseClass::bstring {"."};
If I include the above line in the header along with the class, I get a symbol multiply defined
error. It has to be defined in a separate cpp
file, even with include guards
or pragma once
.
Isn't there a way to define it in the header?
If the initializer can be expressed as a literal, it is solved in C++11:
You can't define a
static
member variable more than once. If you put variable definitions into a header, it is going to be defined in each translation unit where the header is included. Since the include guards are only affecting the compilation of one translation unit, they won't help, either.However, you can define
static
member functions! Now, at first sight that may not look as if it could help except, of course, that function can have localstatic
variable and returning a reference to one of these behaves nearly like astatic
member variable:The local
static
variable will be initialized the first time this function is called. That is, the construction is delayed until the function is accessed the first time. Of course, if you use this function to initialize other global objects it may also make sure that the object is constructed in time. If you use multiple threads this may look like a potential data race but it isn't (unless you use C++03): the initialization of the function localstatic
variable is thread-safe.UPDATE: My answer below explains why this cannot be done in the way suggested by the question. There are at least two answers circumventing this; they may or may not solve the problem.
The
bstring
static member has to be linked to a specific memory address. For this to happen, it has to appear in a single object file, therefore it has to appear in a singlecpp
file. Unless you're playing with#ifdef
's to make sure this happens, what you want cannot be done in the header file, as your header file may be included by more than onecpp
files.To keep the definition of a static value with the declaration in C++11 a nested static structure can be used. In this case the static member is a structure and has to be defined in a .cpp file, but the values are in the header.
Instead of initializing individual members the whole static structure is initialized:
The values are accessed with
Note that this solution still suffers from the problem of the order of initialization of the static variables. When a static value is used to initialize another static variable, the first may not be initialized, yet.
In this case the static variable headers will contain either { "" } or { ".h", ".hpp" }, depending on the order of initialization created by the linker.
No, it can't be done in a header - at least not if the header is included more than once in your source-files, which appears to be the case, or you wouldn't get an error like that. Just stick it in one of the .cpp files and be done with it.
§3.2.6
and the following paragraphs from the current c++ 17 draft (n4296) define the rules when more than one definition can be present in different translation units:Obviously definitions of static data members of class type are not considered to appear in multiple translations units. Thus, according to the standard, it is not allowed.
The suggested answers from Cheers and hth. - Alf and Dietmar are more kind of a "hack", exploiting that definitions of
and
are allowed in multiple TU ( FYI: static functions defined inside a class definition have external linkage and are implicitly defined as inline ) .