How to initialize static members in the header

前端 未结 8 1028
伪装坚强ぢ
伪装坚强ぢ 2020-12-13 09:02

Given is a class with a static member.

class BaseClass
{
public:
    static std::string bstring;
};

String has obviously to be default-

相关标签:
8条回答
  • 2020-12-13 09:25

    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 local static variable and returning a reference to one of these behaves nearly like a static member variable:

    static std::string& bstring() { static std::string rc{"."}; return rc; }
    

    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 local static variable is thread-safe.

    0 讨论(0)
  • 2020-12-13 09:26

    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.

    class BaseClass
    {
    public:
      static struct _Static {
         std::string bstring {"."};
      } global;
    };
    

    Instead of initializing individual members the whole static structure is initialized:

    BaseClass::_Static BaseClass::global;
    

    The values are accessed with

    BaseClass::global.bstring;
    

    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.

    // file.h
    class File {
    public:
      static struct _Extensions {
        const std::string h{ ".h" };
        const std::string hpp{ ".hpp" };
        const std::string c{ ".c" };
        const std::string cpp{ ".cpp" };
      } extension;
    };
    
    // file.cpp
    File::_Extensions File::extension;
    
    // module.cpp
    static std::set<std::string> headers{ File::extension.h, File::extension.hpp };
    

    In this case the static variable headers will contain either { "" } or { ".h", ".hpp" }, depending on the order of initialization created by the linker.

    0 讨论(0)
提交回复
热议问题