Can I initialize a static const member at run-time in C++?

前端 未结 11 1065
小蘑菇
小蘑菇 2020-12-09 16:22

Is it possible to initialize a static const member of my class during run-time? This variable is a constant throughout my program but I want to send it as a command-line arg

11条回答
  •  北海茫月
    2020-12-09 16:50

    Having been facing the same problem myself lately I found @A.S.H 's answer to be the closest to perfect but the fact that the variables have to be initialized so early can cause some problems:

    • Can't use data sources that aren't available yet, such as argc and argv as per the question.
    • Some dependencies might not be initialized yet. For example, many a GUI framework does not allow creating textboxes that early on yet. This is a problem because we might want to display a error textbox if loading the configuration file fails to inform the user.

    So I came up with the following:

    template 
    class StaticConfig
    {
    public:
    
        StaticConfig()
        {
            if (!mIsInitialised)
            {
                throw std::runtime_error("Tried to construct uninitialised StaticConfig!");
            }
        }
    
        const T*
        operator -> () const
        {
            return &mConfig;
        }
    
    private:
    
        friend class ConfigHandler;
    
        StaticConfig(const T& config)
        {
            mConfig = config;
            mIsInitialised = true;
        }
    
        static T mConfig;
        static bool mIsInitialised;
    };
    
    template 
    T StaticConfig::mConfig;
    template 
    bool StaticConfig::mIsInitialised = false;
    

    We make our data static but non-const so we don't have to initialize it immediately and can assign the correct values to it at a more opportune time. Read only access is given trough a overload of operator -> The default constructor checks if a StaticConfig of this type has already been loaded with valid data and throws if it is not. This should never happen in practice but serves as a debugging aid. A private constructor allows loading the type with valid data. A ConfigHandler class, responsible for loading the data, is made a friend so it can access the private constructor.

    A ConfigHandler instance can be briefly created at an opportune time when all the dependencies are available to initialize all the StaticConfig types. Once done, the ConfigHandler instance can be discarded. After that, a class can simply include the appropriate type of StaticConfig as a member and read-only access the data with minimal intrusion.

    Online demonstration.

提交回复
热议问题