Search code examples
c++classconstantsglobal-variablesheader-files

c++ global variables with same name for different classes


Say I have different classes Knight, Spearman, Horseman, ... with exactly same properties: m_health, m_damage, ... (they vary in some methods, so classes are not exactly the same). They have to be initialized in constructor by global default values that are the same for a specific class, but vary across different classess. For example, all Knights have 100 HP and 25 DMG, all Spearmen have 90 HP 40 DMG, but they are different across classes. I don't want to hardcore these values in class contructors, like

class Knight {
public:
    Knight(int health, int damage)
        : m_health(100, 25)
    {}
    ...
}

but rather place these values in a single header file and use them in entire project. What is the best way/practice to do this?

I have tried creating defaultstats.hpp like this:

namespace Default {
    class Knight {
    public:
        static const int HEALTH = 100;
        static const int DAMAGE = 25;
    }

    class Spearman {
    public:
        static const int HEALTH = 90;
        static const int DAMAGE = 40;
    }

    class Horseman {
    public:
        static const int HEALTH = 120;
        static const int DAMAGE = 30;
    }
}

This way I can include header file where globals are needed and access them in intuitive way:

Default::Knight::HEALTH

But is this the best solution? I have read that initializing static variables is unpredictable in terms of ordering and that might be a problem in a big hierarchy of classes and files.

Is there are a idiom or a pattern in doing this efficiently and intuitively?


Solution

  • Just stick the values in the usual classes:

    class Knight {
    public:
        static const int HEALTH = 100;
        static const int DAMAGE = 25;
        
        Knight() : health(HEALTH),
                   damage(DAMAGE) {}
    
        // ...
    };
    

    Alternatively stick 'em in a global configuration querier. That way you can read the values from a config file later if you want.

    std::unordered_map<std::string, double> configuration;
    
    class Knight {
    public:
        Knight() : health(configuration.at("Knight::HEALTH")),
                   damage(configuration.at("Knight::DAMAGE")) {}
        
        // ...
    };