使用const double作为中间结果

4

我正在编写一个模拟程序,想知道在存储中间结果时使用const double是否有用。考虑以下代码片段:

double DoSomeCalculation(const AcModel &model) {
   (...)
   const double V = model.GetVelocity();
   const double m = model.GetMass();
   const double cos_gamma = cos(model.GetFlightPathAngleRad());
   (...)
   return m*V*cos_gamma*Chi_dot;
}

请注意,示例仅用于说明--从工程角度来看可能没有太多意义。将cos_gamma等存储在变量中的动机是因为这个余弦在(...)覆盖的其他表达式中使用了很多次,我觉得使用时代码更加易读。
cos_gamma 

而不是

cos(model.GetFlightPathAngleRad())

在各种表达式中使用cosine。现在实际的问题是:由于我期望余弦在整个代码段中都是相同的,而且我仅将其创建为占位符和便利性,我倾向于声明它为const。关于这是否是好还是坏的惯例,或者这最终会不会影响我,是否有一个已经确立的意见?编译器会利用这些额外的信息吗?还是我实际上阻碍了编译器执行有用的优化?

感谢所有的评论。我认为这个问题已经得到了回答。 - Arne
5个回答

6

关于优化部分我不确定,但我认为将其声明为const是很好的选择。这是因为如果代码很大,那么如果有人在您中间错误地执行了cos_gamma = 1,您将得到编译器错误而不是运行时意外。


4
你可以通过仅计算一次余弦并在所有地方使用它来帮助事情。将该结果设置为const是确保您(或其他人)不会尝试在将来更改它的好方法。
这里的一个好原则是首先使其正确和可读。不要担心编译器可能会进行的任何优化。只有在分析并发现代码确实太慢之后,你才应该担心帮助编译器优化事物。

3

给定你的代码:

const double V = model.GetVelocity();
const double m = model.GetMass();
const double cos_gamma = cos(model.GetFlightPathAngleRad());

我可能会保留cos_gamma不变。我会考虑Vm 改为引用:

const double &V = model.GetVelocity();
const double &m = model.GetMass();

这样做可以明确表明这些只是占位符。然而,这可能会引起生命周期问题--如果你使用一个引用,你必须确保它所引用的内容具有足够的生命周期。从目前的情况看,这可能不是一个问题。首先,GetVelocity()GetMass()可能返回值,而不是引用(在这种情况下,您正在使用临时变量初始化引用,并且临时变量的生命周期延长到初始化它的引用的生命周期)。其次,即使你返回实际的引用,它显然是model的成员,而model(猜测)将在整个计算过程中存在。


谢谢提示。getter方法确实返回模型内部成员的const引用。生命周期不应该是一个问题,因为代码在模拟循环中执行,而模拟循环又确保了模型在作用域内。 - Arne

2

我希望更多的代码像这样编写!

任何可以使您的代码更易读的操作都是好事。只有在需要优化时才进行优化。

我对C++最大的不满之一是默认情况下值不是const。请广泛使用const,保持代码的健康运行!


0

编译器是否利用这一点是一个有趣的问题 - 一旦你处于优化完全工作的程序的阶段。在那之前,你主要为后来的人编写程序,并且必须查看代码。编译器会愉快地吞下(客观上)非常难以阅读的代码,缺少空格、换行符和令人发笑的缩进。人类不会。
最重要的问题是,代码有多易读,以及更改它有多容易出错。在这里,const非常有帮助,因为它使编译器对任何错误更改任何不应更改的内容都会报错。我总是将所有东西都设为const,除非我真的很想让它可变。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接