Home > Blockchain >  C inherit class as static
C inherit class as static

Time:08-20

After reading through How to write a Java-enum-like class with multiple data fields in C ? I decided to give it a try and added some functionality to it. In order to abstract this functionality I've put it in a separate class EnumClass<T>. But since these abstracted features have to be static in the implementation but not in the original class I would need to do something like:

class Planet : public static EnumClass<Planet>

Which is not allowed. Is there some other way to do this? I got around it by adding a static instance of EnumClass<Planet> to Planet, but it is not really optimal:

template<class T, uint64_t S>
class EnumClass {
    public:
        const T elements[S];
        const uint64_t length = S;
        
        template<typename F>
        const T find(F lambda) const {
            for (int i = 0; i < S; i  ) {
                if (lambda(elements[i])) {
                    return elements[i];
                }
            }
            return NULL;
        }
};

template <class T, class... U>
EnumClass(T, U...) -> EnumClass<T, 1   sizeof...(U)>;

class Planet {  
  public: 
    static const Planet MERCURY;  
    static const Planet VENUS;
    
    static constexpr EnumClass ENUM = { &MERCURY, &VENUS };

  private: 
    double massValue;
    double radiusValue;

  private: 
    Planet(double massValue, double radiusValue) {  
        this->massValue = massValue;  
        this->radiusValue = radiusValue;
    } 

  public: 
    double mass() const {
        return this->massValue;
    }
    
    double radius() const {
        return this->radiusValue;
    }
    
    static const Planet* findByMass(double massValue) {
        return ENUM.find([massValue](const Planet * element) { return element->mass() == massValue; });
    }
    
    static const Planet* findByRadius(double radiusValue) {
        return ENUM.find([radiusValue](const Planet * element) { return element->radius() == radiusValue; });
    }
}; 

// Enum value DEFINITIONS 
const Planet Planet::MERCURY = Planet(3.303e 23, 2.4397e6);
const Planet Planet::VENUS = Planet(4.869e 24, 6.0518e6);

CodePudding user response:

If you want members of EnumClass to be static then just make them static. static as in class Planet : public static EnumClass<Planet> does not make sense. You cannot turn non-static members into static members like that.

#include <array>
#include <iostream>
#include <cstddef>

template<class T,size_t S>
class EnumClass {
    public:
        static const std::array<const T*,S> elements;
        static const size_t length = S;
        
        template<typename F>
        static const T* find(F lambda) {
            for (int i = 0; i < S; i  ) {
                if (lambda(elements[i])) {
                    return elements[i];
                }
            }
            return NULL;
        }
};


class Planet : EnumClass<Planet,2> {  
  public: 
    static const Planet MERCURY;  
    static const Planet VENUS;
    
    //static constexpr EnumClass ENUM = { &MERCURY, &VENUS };

  private: 
    double massValue;
    double radiusValue;

  private: 
    Planet(double massValue, double radiusValue) {  
        this->massValue = massValue;  
        this->radiusValue = radiusValue;
    } 

  public: 
    double mass() const {
        return this->massValue;
    }
    
    double radius() const {
        return this->radiusValue;
    }
    
    static const Planet* findByMass(double massValue) {
        return find([massValue](const Planet * element) { return element->mass() == massValue; });
    }
    
    static const Planet* findByRadius(double radiusValue) {
        return find([radiusValue](const Planet * element) { return element->radius() == radiusValue; });
    }
}; 

// Enum value DEFINITIONS 
const Planet Planet::MERCURY = Planet(3.303e 23, 2.4397e6);
const Planet Planet::VENUS = Planet(4.869e 24, 6.0518e6);

template <>
const std::array<const Planet*,2> EnumClass<Planet,2>::elements{{&Planet::MERCURY,&Planet::VENUS}};
  •  Tags:  
  • c
  • Related