我正在尝试使用solution for java-like enums in C++。
我的问题是我正在尝试将枚举用作另一个类的成员。 首先,我们从熟悉的Planet enum开始:
#ifndef PLANETS_H
#define PLANETS_H
class Planet {
public:
static const double G = 6.67300E-11;
// 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:
double surfaceGravity() {
return G * mass / (radius * radius);
}
};
// 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);
#endif // PLANETS_H
然后我们有一个SolarSystem
对象,它接受Planet
个对象。
#ifndef SOLARSYSTEM_H
#define SOLARSYSTEM_H
#include "Planets.h"
class SolarSystem {
public:
SolarSystem(int distance, const Planet& planet) {
this->distance = distance;
this->planet = planet;
}
private:
int distance; // in kilometers
Planet planet;
};
#endif // SOLARSYSTEM_H
现在,如果我们尝试编译它,我们会收到以下错误:
SolarSystem.h: In constructor 'SolarSystem::SolarSystem(int, const Planet&)':
SolarSystem.h:7:53: error: no matching function for call to 'Planet::Planet()'
SolarSystem.h:7:53: note: candidates are:
Planets.h:17:5: note: Planet::Planet(double, double)
Planets.h:17:5: note: candidate expects 2 arguments, 0 provided
Planets.h:4:7: note: Planet::Planet(const Planet&)
Planets.h:4:7: note: candidate expects 1 argument, 0 provided
可以通过包含空的Planet()
构造函数来解决问题。
我想知道这是否是最合适的解决方案,或者是否存在不涉及空构造函数的解决方案。
答案 0 :(得分:3)
您应该将Planet planet
作为引用并在初始化列表中初始化它。否则,C ++会尝试复制Planet
的实例 - 正是您想要避免的事情。
class SolarSystem {
public:
SolarSystem(int distance, const Planet& planet)
: distance(distance)
, planet(planet) {
}
private:
int distance; // in kilometers
const Planet& planet;
};
答案 1 :(得分:1)
如果你使用c ++ 11,你也可以使用我所描述的类似Java的C ++枚举方法(https://stackoverflow.com/a/29594977/558366),它基本上是一个围绕int变量的包装类,并允许你几乎使用Planet好像它是一个普通的枚举类型(它支持与int
之间的转换,并且与int
具有相同的大小),但仍然具有成员函数,例如planet.SurfaceGravity()
。它将允许您的solar系统头编译(尽管您可以并且应该删除构造函数中Planet参数的引用):
class SolarSystem {
public:
SolarSystem(int distance, Planet planet) {
this->distance = distance;
this->planet = planet;
}
private:
int distance; // in kilometers
Planet planet;
};