C++에서 여러 데이터 필드가 있는 Java 열거형 클래스를 작성하는 방법은 무엇입니까?
Java 배경에서 온 저는 C++의 열거형이 매우 형편없다는 것을 알았습니다. C++에서 Java와 같은 열거형(열거형 값이 개체이고 속성과 메서드를 가질 수 있는 열거형)을 작성하는 방법을 알고 싶었습니다.
예를 들어, 다음 Java 코드(기술을 시연하기에 충분함)를 C++로 변환하십시오.
public enum Planet {
MERCURY (3.303e+23, 2.4397e6),
VENUS (4.869e+24, 6.0518e6),
EARTH (5.976e+24, 6.37814e6),
MARS (6.421e+23, 3.3972e6),
JUPITER (1.9e+27, 7.1492e7),
SATURN (5.688e+26, 6.0268e7),
URANUS (8.686e+25, 2.5559e7),
NEPTUNE (1.024e+26, 2.4746e7);
private final double mass; // in kilograms
private final double radius; // in meters
Planet(double mass, double radius) {
this.mass = mass;
this.radius = radius;
}
private double mass() { return mass; }
private double radius() { return radius; }
// universal gravitational constant (m3 kg-1 s-2)
public static final double G = 6.67300E-11;
double surfaceGravity() {
return G * mass / (radius * radius);
}
double surfaceWeight(double otherMass) {
return otherMass * surfaceGravity();
}
public static void main(String[] args) {
if (args.length != 1) {
System.err.println("Usage: java Planet <earth_weight>");
System.exit(-1);
}
double earthWeight = Double.parseDouble(args[0]);
double mass = earthWeight/EARTH.surfaceGravity();
for (Planet p : Planet.values())
System.out.printf("Your weight on %s is %f%n",
p, p.surfaceWeight(mass));
}
}
어떤 도움이라도 대단히 감사하겠습니다!
감사 해요!
Java 열거형을 시뮬레이션하는 한 가지 방법은 자신의 복사본을 정적 변수로 인스턴스화하는 개인 생성자를 사용하여 클래스를 만드는 것입니다.
class Planet {
public:
// Enum value DECLARATIONS - they are defined later
static const Planet MERCURY;
static const Planet VENUS;
// ...
private:
double mass; // in kilograms
double radius; // in meters
private:
Planet(double mass, double radius) {
this->mass = mass;
this->radius = radius;
}
public:
// Properties and methods go here
};
// Enum value DEFINITIONS
// The initialization occurs in the scope of the class,
// so the private Planet constructor can be used.
const Planet Planet::MERCURY = Planet(3.303e+23, 2.4397e6);
const Planet Planet::VENUS = Planet(4.869e+24, 6.0518e6);
// ...
그런 다음 다음과 같이 열거형을 사용할 수 있습니다.
double gravityOnMercury = Planet::MERCURY.SurfaceGravity();
C++11의 도입으로 constexpr
. 형식화된 열거형을 구현하는 또 다른 방법이 있습니다. 일반 열거형과 실질적으로 동일하게 작동하지만( int
변수 로 저장되고 switch
명령문 에서 사용할 수 있음 ) 멤버 함수를 가질 수도 있습니다.
헤더 파일에 다음을 입력합니다.
class Planet {
int index;
public:
static constexpr int length() {return 8;}
Planet() : index(0) {}
constexpr explicit Planet(int index) : index(index) {}
constexpr operator int() const { return index; }
double mass() const;
double radius() const;
double surfaceGravity() const;
};
constexpr Planet PLANET_MERCURY(0);
constexpr Planet PLANET_VENUS(1);
constexpr Planet PLANET_EARTH(2);
// etc.
그리고 소스 파일에서:
static double G = 6.67300E-11;
double Planet::mass() {
switch(index) {
case PLANET_MERCURY: return 3.303e+23;
case PLANET_VENUS: return 4.869e+24;
case PLANET_EARTH: return 5.976e+24;
// Etc.
}
}
double Planet::radius() {
// Similar to mass.
}
double Planet::surfaceGravity() {
return G * mass() / (radius() * radius());
}
그러면 다음과 같이 사용할 수 있습니다.
double gravityOnMercury = PLANET_MERCURY.SurfaceGravity();
불행히도 열거 항목은 클래스 본문 내에서 정적 상수로 정의할 수 없습니다. 선언 시 초기화되어야 constexpr
하지만 클래스 내부에서 클래스는 아직 완전한 유형이 아니므로 인스턴스화할 수 없습니다.
이것이 당신이 원하는 것일 수도 있습니다.
#include<iostream>
using namespace std;
class Planet {
double mass,radius;
Planet(double m, double r) : mass(m) : radius(r) {}
public:
static const Planet MERCURY;
void show(){
cout<<mass<<","<<radius<<endl;
}
} ;
const Planet Planet::MERCURY = Planet(1.0,1.2);
int main(){
Planet p = Planet::MERCURY;
p.show();
}
이것은 단지 작은 코드일 뿐이므로 필요에 맞게 수정할 수 있습니다.
이것은 추하고 장황하며 일반적으로 어리석은 방법입니다. 하지만 설명을 위해 완전한 코드 예제를 게시할 것이라고 생각했습니다. 추가 포인트의 경우 템플릿 전문화를 약간만 조정하여 태양 행성에 대한 컴파일 시간 확장 반복을 정의하는 것이 실제로 가능합니다.
#include <string>
#include <sstream>
#include <iostream>
#include <cstdlib>
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 <SolarPlanets planet>
class SolarPlanet : public Planet {
};
template <>
class SolarPlanet<MERCURY> : public Planet {
public:
SolarPlanet() : Planet("MERCURY", 3.303e+23, 2.4397e6) {}
};
template <>
class SolarPlanet<VENUS> : public Planet {
public:
SolarPlanet() : Planet("VENUS", 4.869e+24, 6.0518e6) {}
};
template <>
class SolarPlanet<EARTH> : public Planet {
public:
SolarPlanet() : Planet("EARTH", 5.976e+24, 6.37814e6) {}
};
template <>
class SolarPlanet<MARS> : public Planet {
public:
SolarPlanet() : Planet("MARS", 6.421e+23, 3.3972e6) {}
};
template <>
class SolarPlanet<JUPITER> : public Planet {
public:
SolarPlanet() : Planet("JUPITER", 1.9e+27, 7.1492e7 ) {}
};
template <>
class SolarPlanet<SATURN> : public Planet {
public:
SolarPlanet() : Planet("SATURN", 5.688e+26, 6.0268e7) {}
};
template <>
class SolarPlanet<URANUS> : public Planet {
public:
SolarPlanet() : Planet("URANUS", 8.686e+25, 2.5559e7) {}
};
template <>
class SolarPlanet<NEPTUNE> : 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<EARTH>().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] << " <earth_weight>\n";
return 1;
}
const double earthweight = ::std::atof(argv[1]);
printTerranWeightOnPlanet(::std::cout, earthweight, SolarPlanet<MERCURY>());
printTerranWeightOnPlanet(::std::cout, earthweight, SolarPlanet<VENUS>());
printTerranWeightOnPlanet(::std::cout, earthweight, SolarPlanet<EARTH>());
printTerranWeightOnPlanet(::std::cout, earthweight, SolarPlanet<MARS>());
printTerranWeightOnPlanet(::std::cout, earthweight, SolarPlanet<JUPITER>());
printTerranWeightOnPlanet(::std::cout, earthweight, SolarPlanet<SATURN>());
printTerranWeightOnPlanet(::std::cout, earthweight, SolarPlanet<URANUS>());
printTerranWeightOnPlanet(::std::cout, earthweight, SolarPlanet<NEPTUNE>());
return 0;
}
ReferenceURL : https://stackoverflow.com/questions/1965249/how-to-write-a-java-enum-like-class-with-multiple-data-fields-in-c
'IT이야기' 카테고리의 다른 글
모든 IOS 장치에서 크롬을 디버그하는 방법 (0) | 2021.10.12 |
---|---|
확장 가능한 이미지 스토리지 (0) | 2021.10.12 |
Windows에서 TortoiseHg(Mercurial)가 생성된(Puttygen에서) 개인 키 파일을 사용하도록 하는 방법 (0) | 2021.10.12 |
ASP.NET MVC 면도기 디자이너 (0) | 2021.10.11 |
Java와 비교하여 Groovy의 성능 (0) | 2021.10.11 |