我想编写函数接口,强制用户承认内置常量的语义.例如,我想采取
void rotate(float angle); // Rotate the world by an angle in radians.
Run Code Online (Sandbox Code Playgroud)
并将其更改为
void rotate(Radians angle);
Run Code Online (Sandbox Code Playgroud)
我是否正确地相信制作Radians类的问题在于它会增加代码并使程序变慢.有一个更好的方法吗?
Omn*_*ous 21
不,有可能将一个Radians类应该被大多数不错的编译器优化成一个不比普通浮点慢的东西.您可能对boost.units感兴趣.
事实上,使用boost.units你甚至可以设置它,这样如果有人想以度数传递一个角度,它会在传递给函数之前自动转换为弧度.这可能会使事情变得缓慢,但它会安排它,以便您可以更改函数所需的单位,而无需返回并编辑大量代码.
而且,当你最终想要编辑所有代码时,你可以暂时修复它,以便转换不起作用,让编译器为你找到它.
能够让编译器为你强制执行这样的约束,没有运行时损失,甚至可能为你编写所有转换代码(运行时间非常小),这是C++真正的优点之一,值得增加复杂性在C.
这是一个非常简单的版本,如果你手工编写它,这个类可能会是什么样子:
#include <cmath>
// This class is tiny enough because it has no virtual functions and only one
// data member that it's likely more efficient to pass by value than by
// reference.
class Radians {
public:
// If you don't put in explicit, the compiler will automatically convert a
// float to a Radians for you and undo all of the hard work you did to make
// sure callers express their intentions.
explicit Radians(float radians) : value_(radians) {}
float getValue() const { return value_; }
void setValue(float radians) { value_ = radians; }
float asDegrees() const { return value_ * 180 / M_PI; }
// This allows you to say Radians r = Radians::fromDegrees(something);
static Radians fromDegrees(float degrees) {
return Radians(degrees * M_PI / 180);
}
private:
float value_;
};
Run Code Online (Sandbox Code Playgroud)
注意如何在类体中声明所有函数.这使得它们都隐含地拥有inline
关键字.一个好的编译器将优化所有这些功能.当然,转换函数会生成执行转换的代码,但除此之外它将与裸浮点相同.
这个约束的关键是声明你的构造函数:
class Radians
{
public:
explicit Radians(float value) : m_value(value) {}
private:
float m_value;
};
Run Code Online (Sandbox Code Playgroud)
那样你的用户就无法输入rotate(4.5)
.他们必须打字rotate(Radians(4.5))
.
这是完成此任务的完美方式.这就是使C成为C++的原因.使用您需要的类并封装数据.它不会使程序显着变慢,因为编译器会执行所有优化.
归档时间: |
|
查看次数: |
1014 次 |
最近记录: |