
第3条:尽可能使用 const
const令人赞叹之处就是:你可以通过它来指定一个语义上的约束(一个特定的不能够更改的对象)这一约束由编译器来保证。通过一个const,你可以告诉编译器和其他程序员,你的程序中有一个数值需要保持恒定不变。不管何时,当你需要这样一个数时,你都应该这样做,这样你便可以让编译器来协助你确保这一约束不被破坏。
const 关键字的用途十分广泛。在类的外部,你可以定义全局的或者名字空间域的常量,也可以通过添加 static 关键字来定义文件、函数、或者程序块域的对象。在类的内部,你可以使用它来定义静态的或者非静态的数据成员。对于指针,你可以制定一个指针是否是 const 的,其所指的数据是否是 const 的,或者两者都是 const ,或者两者都不是。
char greeting[] = "Hello"; char *p = greeting; // 非 const 指针,非 const 数据 const char *p = greeting; // 非 const 指针, const 数据 char * const p = greeting; // const 指针,非 const 数据 const char * const p = greeting; // const 指针, const 数据
这样的语法看上去反复无常,实际上并不是这样。如果 const 关键字出现在星号的左边,那么指针所指向的就是一个常量;如果 const 出现在星号的右边,那么指针本身就是一个常量;如果 const 同时出现在星号的两边,那么两者就都是常量。
当所指向的为常量时,一些程序员喜欢把 const 放在类型之前;其他一些人则喜欢放在类型后边,但要在星号的前边。这两种做法没有什么本质的区别,所以下边给出的两个函数声明的参数表实际上是相同的:
void f1(const Widget *pw); // f1 传入一个指向 Widget 对象常量的指针 void f2(Widget const *pw); // f2 也一样
由于这两种形式在实际代码中都会遇到,所以你都要适应。
STL 迭代器是依照指针模型创建的, 所以说一个 iterator 更加像一个指向 T* 的指针。把一个 iterator 声明为 const 的更像是声明一个 const 的指针(也就是声明一个指向 T* const 的指针): iterator 不允许指向不同类型的内容,但是其所指向的内容可以被修改。如果你希望一个迭代器指向某些不能被修改的内容(也就是指向 const T* 的指针),此时你需要一个 const_iterator :
std::vector<int> vec; ... const std::vector<int>::iterator iter = vec.begin(); // iter 就像一个 T* const *iter = 10; // 正确,可以改变 iter 所指向的内容 ++iter; // 出错! Iter 是一个 const std::vector<int>::const_iterator cIter = vec.begin();// cIter 就像一个 const T* *cIter = 10; // 出错! *cIter 是一个 const ++cIter; // 正确,可以改变 cIter
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-62399-1.html
少了100
跟中国实体经济不是因果关系