设为首页 加入收藏

TOP

2.4 const限定符
2013-10-07 00:31:42 来源: 作者: 【 】 浏览:80
Tags:2.4 const 限定

2.4 const限定符

下列for循环语句有两个问题,两个都和使用512作为循环上界有关。

for (int index = 0; index != 512; ++index) {
    // ...
}

第一个问题是程序的可读性。比较index与512有什么意思呢?循环在做什么呢?也就是说512作用何在?[本例中,512被称为魔数(magic number),它的意义在上下文中没有体现出来。好像这个数是魔术般地从空中出现。]

第二个问题是程序的可维护性。假设这个程序非常庞大,512出现了100次。进一步假设在这100次中,有80次是表示某一特殊缓冲区的大小,剩余20次用于其他目的。现在我们需要把缓冲区的大小增大到1024。要实现这一改变,必须检察每个512出现的位置。我们必须确定——在每种情况下都准确地确定——哪些512表示缓冲区大小,而哪些不是。改错一个都会使程序崩溃,又得回过头来重新检查。

解决这两个问题的方法是使用一个初始化为512的对象:

int bufSize = 512;    // input buffer size
for (int index = 0; index != bufSize; ++index) {
     // ...
}

通过使用好记的名字如bufSize,增强了程序的可读性。现在是对对象bufSize测试而不是对字面值常量512测试:

index != bufSize

现在如果想要改变缓冲区大小,就不再需要查找和改正80次出现的地方。而,只有初始化bufSize那行需要修改。这种方法不但明显减少了工作量,而且还大大减少了出错的可能性。

1. 定义const对象

定义一个变量代表某一常数的方法仍然有一个严重的问题。即bufSize是可以被修改的。bufSize可能被有意或无意地修改。const限定符提供了一个解决办法:它把一个对象转换成一个常量。

const int bufSize = 512;     // input buffer size

定义bufSize为常量并初始化为512。变量bufSize仍然是一个左值(2.3.1节),但是现在这个左值是不可修改的。任何修改bufSize的尝试都会导致编译错误:

bufSize = 0; // error: attempt to write to const object

因为常量在定义后就不能被修改,所以定义时必须初始化:

    const std::string hi = "hello!"; // ok: initialized
    const int i, j = 0;  // error: i is uninitialized const

2. const对象默认为文件的局部变量

在全局作用域(2.3.6节)里定义非const变量时,它在整个程序中都可以访问。我们可以把一个非const变量定义在一个文件,假设已经做了合适的声明,就可在另外的文件中使用这个变量:

// file_1.cc
int counter;  // definition
// file_2.cc
extern int counter; // uses counter from file_1
++counter;          // increments counter defined in file_1

与其他变量不同,除非特别说明,在全局作用域声明的const变量是定义该对象的文件的局部变量。此变量只存在于那个文件,不能被其他文件访问。

通过指定const变量为extern,就可以在整个程序中访问const对象:

// file_1.cc
// defines and initializes a const that is accessible to other files
extern const int bufSize = fcn();
// file_2.cc
extern const int bufSize; // uses bufSize from file_1
// uses bufSize defined in file_1
for (int index = 0; index != bufSize; ++index)
       // ...

本程序中,file_1.cc通过函数fcn()的返回值来定义和初始化bufSize。而bufSize定义为extern,也就意味着bufSize可以在其他的文件中使用。file_2.cc中bufSize的声明同样是extern,这种情况下,extern标志着bufSize是一个声明,所以没有初始化式。

非const变量默认为extern。要使const变量能够在其他的文件中访问,必须显式地指定它为extern。

习题                                                              

习题2.22  下列程序段虽然合法,但是风格很糟糕。有什么问题呢?又怎样改善?

   for (int i = 0; i < 100; ++i)
          // process i

习题2.23  下列哪些语句合法?对于那些不合法的使用,解释原因。

   (a) const int buf;
   (b) int cnt = 0;
          const int sz = cnt;
   (c) cnt++; sz++;

【责任编辑:董书 TEL:(010)68476606】

回书目   上一节   下一节

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇2.3.6 名字的作用域 下一篇2.6 typedef名字

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: