条款03:尽可能使用const
@(EffectiveCpp)
“只要某个值保持不变是事实,你就该说出来,因为说出来可以获得编译器的帮助,确保这条约不会被违反” ————《Effective C++》
以const
修饰变量还是很简单的,所以这一条款将大量篇幅用在了讨论const
在函数声明中的应用,特别是const member func
的内容。
1,将返回值声明为const
- 如果以
by value
形式返回,则没有意义 - 如果以
by reference
或者by pointer
形式返回,则应注意声明为const
,以避免无意义的赋值行为。例:
class Ration{...};
const Ration::operator*(const Ration& lhs,const Ration& rhs);
//错误的赋值行为
Ration a,b,c;
(a*b)=c
一个良好的用户自定义类型的特征是它们避免无端的与内置类型不兼容
2,将参数声明为const
如果不需要改动参数,就应将其声明为const
,以避免恼人的错误(=
写成==
)。
3,const
成员函数
p
a
s
s
b
y
r
e
f
e
r
e
n
c
e
t
o
c
o
n
s
t
pass\;by\;reference\;to\;const
passbyreferencetoconst是提升C++程序效率的根本方法
const
用于成员函数,可以帮助该成员函数用于常量对象。(是的,常量对象不能调用non-const成员函数,哪怕该成员函数没有修改任何成员变量,甚至是空转也不行)
const
修饰成员函数的两个作用:
- 告知用户那个函数可以修改对象内容,那个不可以
- 使得操作常量对象成为可能
- 将数据成员声明为
mutable
,使得const
成员函数可以对修改它们(常量对象调用的const
成员函数也可以)
class example
{
public:
example(){};
~example(){};
void testfunc() const
{
cout<<(++data)<<endl;
}
private:
mutable int data = 3;
};
- 在
const
成员函数和non-const
成员函数之间避免重复
书中例子:
class TextBlock
{
public:
const char& operator [](std::size_t position) const
{
...
return text[position]
}
char& operator [](std::szie_t position)
{
return const_cast<char&>(/*将op[] 返回值的const清除*/
static_cast<const TextBlock>(*this))[position] //为this加上const以调用const op[]
}
}
如果const
成员函数和non-const
成员函数之间存在重复,可以通过non-const
成员函数调用const
成员函数来解决,如图上述代码所示。但是不能让const
去调用non-const
成员函数,即便会更简单:因为对象的内容可能会被改变。
const
成员函数和non-const
成员函数,会被视作重载
调用的依据是,对象的常量性。