- 将某些东西声明为 const 可帮助编译器侦测出错误用法。 const 可被施加于任何作用域内的对象、函数参数、函数返回类型、成员函数本体
- 编译器强制实施 bitwise constness,但你编写程序时应该使用“概念上的常量性”(conceptual constness)
- 当 const 和 non- const 成员函数有着实质等价的实现时,令non- const 版本调用 const 版本可避免代码重复
关键字 const 多才多艺,你可以用它在 classes 外部修饰 global 或 namespace 作用域中的常量,或修饰文件、函数、或区块作用域( block scope)中被声明为 static 的对象。你也可以用它修饰 classes 内部的 static 和non- static 成员变量。面对指针,你也可以指出指针自身、指针所指物,或两者都(或都不)是 const。
const最具威力的用法是面对函数声明时的应用。在一个函数声明式内, const 可以和函数返回值、各参数、函数自身(如果是成员函数)产生关联。
令函数返回一个常量值,往往可以降低因使用者错误而造成的意外,而又不至于放弃安全性和高效性
。举个例子
class Rational {...};
const Rational operator* (const Rational& lhs, const Rational& rhs);
Rational a, b, c;
(a * b) = c; //在 a * b 的结果上调用 operator=,将 operator* 的返回值声明为 const 可以预防该动作
const 成员函数
将 const 实施于成员函数的目的,是为了确认该成员函数可作用于 const 对象身上
。
const 成员函数重要的两个理由:
- 它们使 class 接口比较容易被理解。我们可以得知哪个函数可以改动对象内容而哪个函数不行
- 它们使“操作 const 对象”成为可能
两个成员函数如果只是常量性不同,是可以被重载的
。
bitwise const 阵营的人相信,成员函数只有在不更改对象之任何成员变量(static外)时才可以说是 const。也就是说它不更改对象内的任何一个bit。这种观点的好处是能很容易找到违反点:编译器只需寻找成员变量的赋值动作即可。bitwise constness 正是C++对常量性(constness)的定义
,因此 const 成员函数不可以更改对象内任何 non- static 成员变量。
利用 C++ 的一个关键字: mutable(可变的)。mutable 释放掉 non-static 成员变量的 bitwise constness 约束
:
在 const 和 non- const 成员函数中避免重复
class TextBlock {
public:
...
const char& operator[](std:: size t position) const
{
... //边界检验
... //数据访问
... //检验数据完整性
return text[position];
}
//代码重复
char& operator[](std::size_ t position)
{
... //边界检验
... //数据访问
... //检验数据完整性
return text[position];
}
private:
std::string text;
};
我们应该实现 operator[] 的功能一次并使用它两次。也就是说,令其中一个调用另一个。这促使我们将常量性转除(casting away constness)。
class TextBlock {
public:
...
const char& operator[](std:: size t position) const//一如既往
{
... //边界检验
... //数据访问
... //检验数据完整性
return text[position];
}
char& operator[](std::size_ t position)//现在只调用 const op
{
return
const cast<char&>( //将op[]返回值的 const 转除
static_cast<const TextBlock&>(*this) //为*this加上 const
[position] //调用 const op[]
);
}
};
两次转型动作:
第一次:给 *this 添加 const,目的是明确指出调用的是 const operator[],防止 none-const operator[] 无限递归。
第二次:移除 const 属性。该动作只能由 const_cast 来完成。