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
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;
}