这更像是一个样式问题,因为我知道在实践中大多数编译器可能会优化以产生相同的效果,但我一直在阅读,一般来说,你应该总是在范围内声明/定义变量使用。因此,在我无法内联声明的情况下,例如下面的代码片段,我已经考虑将索引变量括在作用域括号中(大括号,不确定在这种情况下你称它们是什么),以便明确地限制这些变量的范围。这是好习惯吗?如果是这样,你能解释一下原因吗?
{
size_t i = 0; // this variable has no use outside of the range-based for loop
for (auto const input : input_vector)
{
neuron_sequence[i].ForceSignal(input);
++i;
}
}
答案 0 :(得分:5)
当然这是一个很好的做法。它明确限制了可以使用该变量的位置。我经常这样做。像这样的范围也用于强制一些对象析构函数运行。
例如:
std::vector<int> v;
v.resize( 10 ); // now holds memory for 10 ints
你如何清理这段记忆?无法调用任何函数或以任何方式手动告诉向量v
清理其内存。解决方案是强制它超出范围(假设我正确使用了交换):
std::vector<int> v;
v.resize( 10 ); // now holds memory for 10 ints
{
std::vector<int> temp;
temp.swap( v );
} // temp goes out of scope and clears the memory that v used to hold
另一种常见用法是在交换机案例中。通常我需要在交换机中创建一个临时变量:
switch( val )
{
case constant:
{
int x = 10;
// ... do stuff
}
}
我记得的最后一个地方就是编写某些代码的测试用例。当经常对单元进行测试时,我只想尽可能快地编写测试代码而不需要花费太多时间。所以,我在一个函数中放置了一堆相关的测试,但是将局部变量包装在不同的范围内只是为了确保我没有遇到任何奇怪的错误(可能通过测试共享迭代器)。
答案 1 :(得分:3)
是的,你应该明确地设定变量范围:
答案 2 :(得分:2)
对于像整数这样的小数据类型,你真的不需要担心,因为正如你所说的那样,编译器会根据变量的 liveness 来优化代码,以及是否 reaches 某个地点。在这种情况下,它更像是一种风格问题。我建议不要经常这样做,因为代码可读性和易维护性也是性能的一个重要因素。
然而,对于复杂类型,限制生命周期可能是有用的。例如,对于内部分配大量内存的向量,如果其范围受限,则可以节省一些空间。
答案 3 :(得分:0)
a
中“范围”{ X a = 1; X b(a, 2); ++a; } ++b;
过早地摧毁b
总体而言 - 选择它是很好的,但是你会在有需要的时候产生一种感觉。如果不确定,那可能无关紧要。