Search code examples
c++staticg++

How to initialize static members of a class?


I have written this code. It is giving no compile time errors but a runtime error. Can you please tell me what is wrong with this code?

It is giving this runtime error -> strap info: vpid 1: terminated with signal 11

    #include <iostream>

    class Color
    {
    public:
        static Color White, Black, Red, Green, Blue;

        unsigned char red, green, blue;

        static void static_Color();

        Color(unsigned char _red
        , unsigned char _green
        , unsigned char _blue)
        : red(_red), green(_green), blue(_blue)
        {
            static_Color();
        }
        
        Color()
        {
            static_Color();
        }
    };
    
    Color Color::White, Color::Black
    , Color::Red, Color::Green, Color::Blue;
    
    void Color::static_Color()
    {
        static bool called_before = false;

        if(called_before)
            return;

        Color::White = Color(255, 255, 255);
        Color::Black = Color(0, 0, 0);
        Color::Red = Color(255, 0, 0);
        Color::Green = Color(0, 255, 0);
        Color::Blue = Color(0, 0, 255);

        called_before = true;
    }
    
    int main()
    {
        std::cout << (int) Color::Red.red;
    }

A needed feature static constructor.


Solution

  • You don't need a static_Color() function. Just initialize them with the proper values where the static colors are defined:

    class Color {
    public:
        static Color White, Black, Red, Green, Blue;
    
        unsigned char red = 0, green = 0, blue = 0;
    
        Color(unsigned char _red, unsigned char _green, unsigned char _blue)
            : red(_red), green(_green), blue(_blue) {}
    
        Color() = default;
    };
    
    // Here:
    Color Color::White = Color(255, 255, 255);
    Color Color::Black = Color(0, 0, 0);
    Color Color::Red = Color(255, 0, 0);
    Color Color::Green = Color(0, 255, 0);
    Color Color::Blue = Color(0, 0, 255);
    

    Right now, your the call to static_Color() in your constructor causes infinite recursion since every construction of a Color will cause a call to static_Color() that will again construct more Colors.


    An alternative to having static member variables is to make some constants in your namespace. I've called the namespace Color too. You figure out a better one:

    namespace Color {
    class Color {
    public:
        unsigned char red = 0, green = 0, blue = 0;
    
        constexpr Color(unsigned char _red, unsigned char _green, unsigned char _blue)
            : red(_red), green(_green), blue(_blue) {}
    
        Color() = default;
    };
    
    inline constexpr Color White = Color(255, 255, 255);
    inline constexpr Color Black = Color(0, 0, 0);
    inline constexpr Color Red = Color(255, 0, 0);
    inline constexpr Color Green = Color(0, 255, 0);
    inline constexpr Color Blue = Color(0, 0, 255);
    }  // namespace Color