原则上在编译阶段可以暴露出来的问题,就不要放到执行阶段。
因此啊,如果你确定一个值时保持不变的,你就应该说出来---const
1.对于指针
char greeting[] = "xujian";
char* p = greeting;
const char* p = greeting; //表示被指物是常量
char* const p = greeting;//表示指针是常量
const char* const p = greeting;//均为常量
即const出现在星号左边表示被指物是常量,出现在右边表示指针自身是常量。
其中const char *p == char const * p
2.对于函数
class Rational{};
const Rational operator*{...}
Rational a,b,c;
(a*b) = c; //可以直接编译不过,防止低级错误
3. const 成员函数
用于确认该成员函数是否可作用于const对象身上。
const 成员函数的目的为:
a.可以得知哪个函数可以改动对象内容而哪个函数不行。
b.“操作const对象”成为可能,方便参数传递时直接传递const 引用
注意:const成员函数可以被重载
class TextBlock{
public:
const char& operator[]() const; //const 成员函数
char& operator[]; //非const成员函数
}
TextBlock tb("Hello");
std::cout <<tb[0]; //调用非const成员函数
tb[0] = '1' //正确---返回的是引用
//若函数的返回类型为内置类型,那么改动函数的返回值不合法
const TextBlock ctb("World");
std::cout<<ctb[0]; //调用const成员函数
ctb[0] = '1' //错误
const 成员函数到底意味着什么?
1.观点一:成员函数不更改除静态成员变量的任何变量时才能称为const成员函数。
此类观点存在的问题展示:
class CTextBlock
{
public:
const char& operator[]() const; //const 成员函数
}
//将operator[]声明为const成员函数,返回一个对象内部值的引用。
const CTextBlock cct("Hello");//声明一个常量对象
char* pc = &cctb[0]; //调用const operator[]取得指针
*pc = 'J'; //更改了常量对象
2.观点二:const成员函数在编译器侦测不出的情况下,可以更改某些内部变量。
问题展示:
class CTextBlock{
public:
std:size_t length() const;
private:
char* pText;
std::size_t textLength; //最近一次计算的文本区长度
bool lengthIsValid; //目前长度是否有效
}
std::size_t CTextBlock::length() const
{
if(!lengthIsValid)
{
textLength = std::strlen(pText);//编译器报错
lengthIsValid = true; //
}
return textLength;
}
解决方法:此观点写出的函数编译器可能无法通过,此时需要将const函数可以改变的变量声明为mutable
另外:当const 和 non-const成员函数有着实质等价的实现时,另non-const版本调用const版本可以避免代码重复。
const char& operator[](std:size position)
{
return const_cast<char&>( //调用const_cast转出const属性
static_cast<const TextBlock&>(*this)
[position];
}