What would be the best practice in C++, to define two separate constructors, one having input in degrees whilst the other in radians? The problem I'm having doing it the straight forward way is that the signature of both methods look the same to the compiler, even though the parameter names identify which is which, and the compiler flags a re-declaration
error. Is this possible to do without introducing another field?
I can do it using a single constructor by adding an additional bool parameter that would allow selecting which units are being passed, and using an if in the body.
Use the named constructor idiom. Make your constructor private, and pick whichever you prefer for the argument type, degrees or radians. Then make appropriately named static member functions which do the necessary conversion.
class Angle {
public:
static Angle radians(double r) { return Angle(r); }
static Angle degrees(double d) { return Angle(d / 180.0 * PI); }
private:
double angle_in_radians;
Angle(double r) :angle_in_radians(r) {}
};
What would be the best practice in C++, to define two separate constructors, one having input in degrees whilst the other in radians?
The best practice would be to have only a single constructor that clearly takes only one of them (most probably radians, since all the trigonometrical functions work with radians).
You should have additional functions to convert the values. One way is to use user defined literals1.
These are meant to give plain values a context with a particular unit to use.
I would go the following way:
constexpr long double operator"" _deg ( long double deg )
{
return deg2rad(deg);
}
long double deg2rad(long double deg) {
return deg*3.141592/180;
}
long double rad2deg(long double rad) {
return (rad/3.141592)*180;
}
class Angle {
public:
/**
* Default constructor.
*/
Angle() : radians() {}
/**
* Takes the initial angle value as radians.
*/
Angle(long double rad) : radians(rad) {}
// Convenience setters and getters
void rad(long double value) {
radians = value;
}
long double rad() const {
return radians;
}
void deg(long double value) {
radians = deg2rad(value);
}
long double deg() const {
return rad2deg(radians);
}
private:
long double radians; // Only use radians internally
};
int main() {
Angle ang1(180_deg); // Initialize using the constexpr conversion
long double deg = 0;
std::cout << "Enter an angle value in degrees: " << std::flush;
std::cin >> deg;
Angle ang2(deg2rad(deg));
}
1The examples from the documentation even have one for converting degrees to radians.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With