const與指針
void foo()
{
char sz[] = "Hello World";
char *psz = sz;
char *const cpsz = sz;
const char *pcsz = sz;
const char * const cpcsz = sz;
psz[0] = 'J'; // ok
// cpsz++; // error, cpsz is const
// pcsz[0] = 'K';// error, pcsz[0] is const
vector<int> vec;
const vector<int>::iterator cit; // cit is const, like char *const p
vector<int>::const_iterator itc; // point to const, like const char *p
}
const與傳回值
struct Complex
{
Complex(double a, double b):m_a(a), m_b(b)
{}
double m_a;
double m_b;
};
// 1. 傳回類型不能是臨時對象的引用
// 2. 傳回const對象避免(a*b) = c,(a*b)傳回的是const對象,不能指派
const Complex operator*(const Complex& l, const Complex& r)
{
return Complex(l.m_a * r.m_a,
l.m_b * r.m_b);
}
const與成員函數
class Foo
{
public:
// f1
const char& operator[] (const string::size_type pos) const
{
// ...
return m_data[pos];
}
// f2
//char& operator[] (const string::size_type pos)
//{
// // ...
// return m_data[pos];
//}
// 避免f1和f2代碼重複的技術
char& operator[] (const string::size_type pos)
{
// 1. 調用此方法的對象必定是一個none const對象,是以const_cast是安全的
// 2. 用static_cast把this轉成一個const對象,明确調用const版本operator[],避免遞歸
return const_cast<char&>(
static_cast<const Foo&>(*this)[pos]);
}
private:
static string m_data;
};
string Foo::m_data = "Hello World";
void print_char(const Foo& f)
{
cout << f[0]; // 調用且隻能調用f1,因為f是const對象
}
void set_char(Foo &f)
{
f[0] = 'K'; // 調用且隻能調用f2,因為f2的傳回才可被指派
}
const的bitwise和logical
class Text
{
public:
// 計算長度的方法,應聲明為const
const string::size_type length() const
{
if (!m_bLengthValid)
{
// 這裡要緩存text的長度,需要将m_length聲明為mutable
m_length = m_text.length();
m_bLengthValid = true;
}
return m_length;
}
private:
string m_text;
// 聲明為mutable,即使在const方法内也可以被修改,這就是logical const
mutable string::size_type m_length;
mutable bool m_bLengthValid;
};