限制变量范围的利弊
Pro and cons of restrict the scope of variable
摘自《C++编程语言4版》一书,作者喜欢限制变量的作用域。它位于"3.2.1.3 初始化容器"一章中
代码为:
Vector read(istream& is)
{
Vector v;
for (double d; is>>d;) // read floating-point values into d
v.push_back(d); // add d to v
return v;
}
他说
我使用了for语句而不是更传统的语句 while-语句,以将 d 的作用域限制在循环中。
这样做有什么好处?
限制范围意味着:
-
RAII 类型(管理文件或网络 I/O 句柄、内存、线程锁等资源并在其析构函数中释放这些资源(使其析构函数的清理代码更早而不是更晚地运行,从而优化资源使用持续时间,对它们自己和其他程序的执行具有潜在的流动优势
-
后面的代码可以出于其他目的重用相同的标识符......如果变量名称在不同的循环中服务于相同的逻辑目的,但恰好在类型上不同,为什么还要继续梦想变量名称?
-
没有尝试重用变量的风险,在早期不相关的使用后忘记重置其值
阅读代码的程序员在分析代码时使用的范围 后不需要记住它;总而言之,自信地理解代码所需的交叉引用和搜索要少得多。
您可以在各种使用上下文中使用
auto
以避免此类错误...
float x;
for (x = my_floats.first(); x < 10; x = my_floats.next())
...
for (x = my_doubles.first(); x < 10; x = my_doubles.next())
... oops... getting float precision when double available...
- 如果随着代码
- 的发展,您希望更改变量名称和/或类型以反映其用法,则可以更轻松地以本地化方式执行此操作,而不会使名称通过其他代码产生误导,或者类型变得不合适(可能像上面的
float
/double
示例一样默默地降低结果(; 即使没有具有"重构"支持的花哨IDE, 编译器错误可以帮助您在本地范围内准确地进行更改,而无需执行(更容易出错的(全局搜索和替换...
除了@TonyD的回答:
-
理想情况下,您应该尽可能靠近使用它们的地点声明变量。
这使得代码在未到达使用值的执行分支时更快。
例:
void f() { std::string s{ "will be interesting later" ); // some local variable that // could have been declared // lower in the code void g(); // may throw use(s); }
根据 s 的大小,分配它可能是一项昂贵的操作。但是,如果
g
抛出,将不需要s
,并且分配给它的资源将被浪费。在调用 g 之前分配s
也意味着 g 将以较少的可用资源运行(考虑到当今计算机的功能,在大多数情况下,这实际上可能无关紧要(。 -
声明靠近使用它们的位置意味着无需滚动以查看类型定义。您必须向上滚动才能看到的声明是"看不见的"(因此,在脑海中:)(。
-
编辑/手动重构。考虑想要提取对
use
不同函数的调用:如果上面的代码没有调用g
中间,你可以复制和粘贴。这样,您可以粘贴整个块,然后删除对g
的调用,或者复制两次(用于定义s
和调用use
(。
for 循环范围内声明和初始化变量i
的最简单原因是保持代码易于调试和理解,并防止计数器变量在整个程序中不必要地使用内存 execution.ie
在下面的代码中,变量 i 超出 for 循环的范围也会影响 for 循环之外的代码。但是,它仅用作循环的计数器变量。仅当您要保留和使用循环范围之外的循环计数器的值时,才应采用此样式。
int main()
{
int bigNumber = 10;
int i;
for(i = 0; i != bigNumber; ++i){
cout<<i;
if(i==2)
break;
}
cout<<"loop terminated at"<<i;
return 0;
}
就第二种样式而言,它确保变量i
的作用和值仅在循环范围之前受到限制。在下面给出的代码中,您将无法在循环范围之外使用计数器变量,从而导致错误。这有助于防止计数器变量不必要的内存使用。
int main()
{
int bigNumber = 10;
for(int i = 0; i != bigNumber; ++i){
cout<<i;
}
cout<<i;
return 0;
}
- 尝试通过多个向量访问变量时,向量下标超出范围
- 绑定派生类方法C++从实例范围之外的分隔 std::function 变量调用
- 是否可以依赖函数范围的静态变量来执行程序关闭期间调用的方法?
- 如果非动态变量被指针引用,何时超出范围?
- 为什么我的变量存在于其范围之外
- 变量超出范围后如何保留向量值?
- 将引用分配给局部变量,如果局部变量超出范围,它会超出范围吗?
- 在C++中使用变量而不是"#define"来指定数组大小是不是一种糟糕的做法?(C错误:在文件范围内
- 在 c++ 中确定堆栈上的变量范围
- 如何改进一堆在已知值范围内评估变量的 else-if 条件?
- 如何从未知视图中声明范围::v3::View 变量
- 如果变量数据包含大于 vector 所有元素的整数,则仅在视觉工作室上接收"矢量下标超出范围"?
- 是否未定义将对函数范围变量的引用作为值返回
- 无法从另一个函数访问文件范围变量的内容
- 如何访问C 中的功能范围变量
- C++ 程序和范围变量
- 性能对象属性与范围变量
- 存储lambda函数,该函数将范围变量捕获为类成员以供重用
- 何时分配块范围变量
- 在 c++ 中声明一个全局范围变量 const