tip3:尽可能使用const
const允许你指定一个语义约束(也就是指定一个“不该被改动”的对象),与它含义相反的关键字是mutable。
先来探讨下表达形式的相关问题:
void f1(const Widget* pw)
void f2(Widget const * pw)
这两个函数的参数都是指向常量的指针
我个人的理解方式是:除非const后面紧跟指针名,例如char* const p,这种情况是一个常指针,其他时候我都理解为指针指向常量
const在函数中的应用
令函数返回值为一个常值,往往可以降低因客户错误而造成的意外,而又不至于放弃安全性和高效性。
因为由于返回值不可修改,不会出现错误的赋值或其他修改操作。
至于const参数,除非你有需要改动的参数或者local对象,否则请将参数声明为const。
const成员函数
将const实施于成员函数的目的是为了确认该成员函数可以作用于const对象身上,因为const对象只能调用const成员函数
许多人漠视的一个事实:两个成员函数如果只是常量性不同,可以被重载
成员函数如果是const意味着什么?这有两个流行概念:bitwise constness 和 logical constness
bitwise constness 阵营的人相信,成员函数只有在不更改对象之任何成员变量时才可以说是const
(PS:此时书上举了一个例子,是为了证明以下行为没有错误:创建一个常量对象并设以某值,而且只对它调用const成员函数,但你终究还是改变了它的值。但是以我使用VS2017进行测试的情况来看,现在的IDE对const char * 和char * 的区分非常的严格,根本不给我通过编译的机会。我并不能做到书上例子的操作,可能是因为我技术能力有限,但是毋庸置疑的是现在的C++检查标准已经更加严格了,我们或许能回避掉以前的这种问题。)
所谓的logical constness:一个const成员函数可以修改他所处理的对象内的某些bits,但只有在客户端侦测不出的情况下才得如此。
利用C++的一个与const相关的摆动场:mutable
被mutable修饰的的成员变量可能总是会被更改,即使在const成员函数里面,可以解决“bitwise constness非我所欲 ”的问题。
在 const 和 non-const 成员函数中避免重复
书中举例到,如果成员函数功能太多,为了同时拥有const成员函数和它的重载non-const成员函数,选择复制代码段的话重复的代码太多了。
此时必须令其中一个调用另一个,促使我们将常量性移除,下面为书中例子:
class TextBlock{
public:
...
const char& operator[](std::size_t position) const
{
...
...
return text[position];
}
char& operator[](std::size_t position)
{
return
const_cast<char&>( //将op[]返回值的const转除
static_cast<const TextBlock&>(*this) //为*this加上const
[position] //调用const op[]
);
}
...
};
反向做法——令const版本调用non-const版本以避免重复——并不是你该做的事情。csont成员函数承诺绝不改变其对象的逻辑状态,non-const成员函数却没有这般承诺。
将某些东西声明为const可帮助编译器侦测出错误用法。const可被施加于任何作用域内的对象、函数参数、函数返回类型、成员函数本体。
编译器强制实施bitwise constness,但你编写程序时应该使用“概念上的常量性”。
当const和non-const成员函数有着实质等价的实现时,令non-const版本调用const版本可避免代码重复。