/*
*
*本博文以及这个系列的都是我本人观看《Effective C++》的观后感,每天学习一个改善自己C++的一个小技巧。
*
*
条款03:尽可能使用const
-
const它允许你指定一个语义的约束(指定一个不该被修改的对象)(就是定义一个常量),而编译器会强制实施这个约束,编译器可以帮助你告诉你的客户改数据不应该被改变。
-
const它可以作用于类外部修饰全部变量或名字空间作用域(namespace)的常量,或是修饰文件、函数、区块作用域(局部)中被声明为static的对象。
-
也可以作用于修饰类内部的静态和非静态成员变量。
-
面对指针,可以指出指针自身、指针所指物、或是两者不可以修改。
char str[] = "Hello";
char* p = str; //都可以修改
const char* p = str; //数据不可以修改,指针可以修改
char* const p = str; //指针不可以修改,数据可以修改
const char* const p = str; //指针和数据都不可以修改
技巧:
1.const出现在星号的左边指针可以修改,数据不可以修改。
2.const出现在星号的右边指针不可以修改,数据可以修改。
3.两个const表示都不可以修改.
下面两种写法代表的意思一致,都有人用
void func1(const int* a)
{
//...
}
void func2(int const* a) // func1、func2都是获取同一类型的参数
{
//...
}
给STL迭代器用const应该这样写
int main()
{
vector<int> v;
const vector<int>::iterator it1 = v.begin(); //指针是常量,所指数据不是。
*it1 = 2;
//it1++; //出错,it1是const
vector<int>::const_iterator it2 = v.begin(); //数据是常量,指针不是。
*it2++;
//*it2 = 3; //出错, *it2是const
}
令函数返回值为const
class Rational {
//..
};
const Rational operator*(const Rational& lhr, const Rational& rhs)
{
//..
}
//如果不这样做客户可能出现下面的做法,给两个数值的乘积赋值.
//也许客户的本意是if(a*b == c)少打一个=造成的错误,加上const就会省下恼人的错误
int main()
{
Rational a, b, c;
//(a * b) = c; //函数返回值const的话这句话就报错提醒
}
const成员函数
给成员函数加const的原因
1.它使类的接口比较容易被理解。可以得知哪个函数可以改变对象内容。
2.它使“操作const对象”成为可能。
两个成员函数只是常量性不同,可以被重载
class TextBook
{
public:
TextBook(string str)
{
this->text = str;
}
const char& operator[](size_t position)const //const版本
{
return text[position];
}
char& operator[](size_t position) //非const版本
{
return text[position];
}
private:
string text;
};
int main()
{
TextBook tb("Hello"); //非const版本
const TextBook ctb("World"); //const版本
cout << tb[0] << endl; //读合法
tb[0] = 'X'; //写合法
cout << ctb[0] << endl; //读合法
//ctb[0] = 'x'; //写不合法
}
一个与const对立的关键字mutable
class CTextBook
{
public:
size_t length()const;
private:
char* pText;
mutable size_t textLength;
mutable bool lengthIsValid; //这些成员是可变的即使在const成员函数内
};
size_t CTextBook::length()const //一般来说在const成员函数内不能给成员赋值
{
if (!lengthIsValid)
{
textLength = strlen(pText);
lengthIsValid = true; //因为给textLength和lengthIsValid加上mutable才能合法赋值
}
return textLength;
}