天天看點

constconst與指針const與傳回值const與成員函數const的bitwise和logical

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;
};
           

繼續閱讀