How to write a Java-enum-like class with multiple data fields in C++?

前端 未结 4 684
感情败类
感情败类 2020-11-30 21:32

Coming from a Java background, I find C++\'s enums very lame. I wanted to know how to write Java-like enums (the ones in which the enum values are objects, and can have attr

4条回答
  •  醉梦人生
    2020-11-30 21:43

    This is ugly, verbose, and generally a dumb way to go. But I figured I'd post a complete code example by way of explanation. For extra points it's actually possible to define a compile-time expanded iteration over the solar planets by tweaking the template specializations just a tad.

    #include 
    #include 
    #include 
    #include 
    
    class Planet {
     public:
       static const double G = 6.67300E-11;
    
       Planet(const ::std::string &name, double mass, double radius)
            : name_(name), mass_(mass), radius_(radius)
          {}
       const ::std::string &name() const { return name_; }
       double surfaceGravity() const {
          return G * mass_ / (radius_ * radius_);
       }
       double surfaceWeight(double otherMass) const {
          return otherMass * surfaceGravity();
       }
    
     private:
       const ::std::string name_;
       const double mass_;
       const double radius_;
    };
    
    enum SolarPlanets {
       MERCURY,
       VENUS,
       EARTH,
       MARS,
       JUPITER,
       SATURN,
       URANUS,
       NEPTUNE
    };
    
    template 
    class SolarPlanet : public Planet {
    };
    
    template <>
    class SolarPlanet : public Planet {
     public:
       SolarPlanet() : Planet("MERCURY", 3.303e+23, 2.4397e6) {}
    };
    
    template <>
    class SolarPlanet : public Planet {
     public:
       SolarPlanet() : Planet("VENUS", 4.869e+24, 6.0518e6) {}
    };
    
    template <>
    class SolarPlanet : public Planet {
     public:
       SolarPlanet() : Planet("EARTH", 5.976e+24, 6.37814e6) {}
    };
    
    template <>
    class SolarPlanet : public Planet {
     public:
       SolarPlanet() : Planet("MARS", 6.421e+23, 3.3972e6) {}
    };
    
    template <>
    class SolarPlanet : public Planet {
     public:
       SolarPlanet() : Planet("JUPITER", 1.9e+27, 7.1492e7 ) {}
    };
    
    template <>
    class SolarPlanet : public Planet {
     public:
       SolarPlanet() : Planet("SATURN", 5.688e+26, 6.0268e7) {}
    };
    
    template <>
    class SolarPlanet : public Planet {
     public:
       SolarPlanet() : Planet("URANUS", 8.686e+25, 2.5559e7) {}
    };
    
    template <>
    class SolarPlanet : public Planet {
     public:
       SolarPlanet() : Planet("NEPTUNE", 1.024e+26, 2.4746e7) {}
    };
    
    void printTerranWeightOnPlanet(
       ::std::ostream &os, double terran_mass, const Planet &p
       )
    {
       const double mass = terran_mass / SolarPlanet().surfaceGravity();
       os << "Your weight on " << p.name() << " is " << p.surfaceWeight(mass) << '\n';
    }
    
    int main(int argc, const char *argv[])
    {
       if (argc != 2) {
          ::std::cerr << "Usage: " << argv[0] << " \n";
          return 1;
       }
       const double earthweight = ::std::atof(argv[1]);
       printTerranWeightOnPlanet(::std::cout, earthweight, SolarPlanet());
       printTerranWeightOnPlanet(::std::cout, earthweight, SolarPlanet());
       printTerranWeightOnPlanet(::std::cout, earthweight, SolarPlanet());
       printTerranWeightOnPlanet(::std::cout, earthweight, SolarPlanet());
       printTerranWeightOnPlanet(::std::cout, earthweight, SolarPlanet());
       printTerranWeightOnPlanet(::std::cout, earthweight, SolarPlanet());
       printTerranWeightOnPlanet(::std::cout, earthweight, SolarPlanet());
       printTerranWeightOnPlanet(::std::cout, earthweight, SolarPlanet());
       return 0;
    }
    

提交回复
热议问题