6

这更像是一个风格问题,因为我知道在实践中大多数编译器可能会优化以提供相同的效果,但我一直在阅读,一般来说,您应该始终在使用它们的范围内声明/定义变量。因此,在我无法内联声明的情况下,例如以下代码段,我考虑将索引变量括在范围括号(大括号,在这种情况下不确定您如何称呼它们)中,以明确限制这些变量的范围。这是好习惯吗?如果是这样,你能解释一下为什么吗?

{
    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;
    }
}
4

4 回答 4

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 case 中。很多时候我需要在开关中创建一个临时变量:

switch( val )
{
case constant:
  {
    int x = 10;
    // ... do stuff
  }
}

我能记住的最后一个地方是为某种代码编写测试用例时。经常进行单元测试时,我只想尽可能快地编写测试代码,而不需要花费太多的开发时间。所以,我将一堆相关的测试放在一个函数中,但将局部变量包装在不同的范围内,以确保我不会遇到任何奇怪的错误(也许通过测试共享迭代器)。

于 2013-04-22T05:06:29.513 回答
3

是的,您应该明确范围变量:

  1. 作用域定义了局部变量的生命周期,因此适当地定义变量的作用域意味着变量只有在它们服务于它们所需的用途之前才是活动的,而不仅仅是活动和占用内存。
  2. 在相同命名变量的情况下,局部变量隐藏或隐藏相同命名的全局变量。因此,明确范围可以提高读者的可读性。(至少我是这么认为的)
于 2013-04-22T05:05:58.393 回答
2

对于像整数这样的小数据类型,你真的不需要担心,因为正如你所说,编译器会根据变量的活跃度以及它是否到达某个位置来优化代码。在这种情况下,它更多的是风格问题。而且我建议不要经常这样做,因为代码可读性和易于维护也与性能一样重要。

然而,对于复杂类型,限制这样的生命周期可能很有用。例如,对于内部分配大量内存的向量,如果其范围受到限制,则可以节省一些空间。

于 2013-04-22T05:06:17.663 回答
0
  • 当您发现自己担心对象的生命周期时,紧密的范围是好的 - 通常是因为使用的内存/资源,或者希望防止意外或促进故意重用相同的标识符
    • 例如,做一些重复的操作——甚至可能使用宏替换——需要一个临时的但更改名称没有特殊目的并且很乏味
  • 你不能总是这样做:你会遇到很多情况,其中适合一个变量的最紧密的范围与另一个变量的范围重叠:例如,试图“范围a{ X a = 1; X b(a, 2); ++a; } ++b;破坏b太早
  • 在某些情况下,创建大量的小范围会使源代码变得相当臃肿,使其更难直观地接受和维护。需要花费一些精力来检查引入的范围是否没有控制 if/for/while 语句,并且很难一目了然地看到整个函数流程。当然,减少函数范围内的变量数量也可以减少脑力劳动 - 所以这是一种平衡行为。

总的来说 - 有选择性是很好的,但你会感觉到什么时候有必要。如果不确定,可能没关系。

于 2013-04-22T05:49:08.580 回答