条款03: 尽可能使用const

1. 在classes外部修饰global或namespace作用域内的常量,或修饰文件、函数、或区块作用域中被声明为static的对象
2. 修饰classes内部的static和non-static成员变量
3. 可以指出指针自身、指针所指之物,或两者都不是,都是const

char greeting[] = "Hello";
char* const p00 = greeting;//const pointer
const char* p01 = greeting;//const data
char const* p02 = greeting;//const data
char* p03 = greeting;//non const
const char* const p04 = greeting; //const data/pointer

1. 声明迭代器为const就像声明指针为const一样(即T*const),表示这个迭代器不得指向不同的东西,但所指的东西值是可以改动的
2. 希望迭代器所指的东西不可改动(即const*T),需要的是const_iterator

void Test00()
{
    std::vector<int> vec(1);
    const std::vector<int>::iterator Iter = vec.begin();
    *Iter = 10;
    //++Iter; //const pointer

    std::vector<int>::const_iterator cIter = vec.begin();
    //*cIter = 10; //const data
    ++cIter;
}

1. 令函数返回一个常量值,往往可以降低因客户错误而造成的损失,而又不至于放弃安全性和高效性

class Rational
{
public:
    Rational() = default;
    ~Rational() = default;
};

const Rational operator*(const Rational& lhs, const Rational& rhs)
{
    return Rational();
}

void Test01()
{
    Rational A, B, C;
    A = B * C;
    //B* C = A; //const 不能再赋值
}

1. const成员函数可作用于const对象,class接口容易理解
2. 两个成员函数const和非const可以重载

class TextBlock
{
public:
    TextBlock(const std::string& sText) :
        text(sText)
    {}
    const char& operator[](std::size_t position)const
    {
        std::cout << "const ";
        return text[position];
    }
    char& operator[](std::size_t position)
    {
        std::cout << "no const ";
        return text[position];
    }
private:
    std::string text;
};

void Test02()
{
    TextBlock tb("Hello");
    tb[0] = 'X';
    std::cout << tb[0] << std::endl;

    const TextBlock ctb("World");
    //ctb[0] = 'X'; //const data
    std::cout << ctb[0] << std::endl;
}

1. 利用mutable 释放掉non-static成员变量的const约束

class CTextBlock
{
public:
    CTextBlock(const std::string& sText) :
        text(sText)
    {}
    std::size_t length()const
    {
        if (!lengthIsValid)
        {
            textLength = text.length(); //const函数可以修改
            lengthIsValid = true;
        }
    }
private:
    std::string text;
    mutable std::size_t textLength;
    mutable bool lengthIsValid;
};

1. non-const调用const 成员函数避免重复
2. 第一次转换为*this添加const,接下来调用const成员函数
3. 第二次转换在返回值移除const

class CastTextBlock
{
public:
    CastTextBlock(const std::string& sText) :
        text(sText)
    {}
    const char& operator[](std::size_t position)const
    {
        std::cout << "const ";
        return text[position];
    }
    char& operator[](std::size_t position)
    {
        std::cout << "no const ";
        return const_cast<char&>
            (static_cast<const CastTextBlock&>(*this)[position]);
    }
private:
    std::string text;
};

void Test03()
{
    TextBlock tb("Hello");
    tb[0] = 'X';
    std::cout << tb[0] << std::endl;

    const TextBlock ctb("World");
    //ctb[0] = 'X'; //const data
    std::cout << ctb[0] << std::endl;
}

int main()
{
    Test00();
    Test01();
    Test02();
    Test03();
    return EXIT_SUCCESS;
}

  

posted @ 2024-09-07 14:59  博瑜图形  阅读(17)  评论(0)    收藏  举报