zoukankan      html  css  js  c++  java
  • Effective C++ 笔记 —— Item 3: Use const whenever possible

    The following functions take the same parameter type:

    void f1(const Widget *pw); // f1 takes a pointer to a constant Widget object
    void f2(Widget const *pw); // so does f2

    Consider a class for representing a block of text:

    class TextBlock 
    {
    public:
        const char& operator[](std::size_t position) const // operator[] for const objects
        {
            return text[position];
        } 
        char& operator[](std::size_t position) // operator[] for non-const objects
        {
            return text[position];
        }
    private:
        std::string text;
    };
    
    TextBlock tb("Hello");
    std::cout << tb[0]; // calls non-const TextBlock::operator[]
    const TextBlock ctb("World");
    std::cout << ctb[0]; // calls const TextBlock::operator[]
    
    std::cout << tb[0]; // fine—reading a non-const TextBlock
    tb[0] = ’x’; // fine—writing a non-const TextBlock
    std::cout << ctb[0]; // fine—reading a const TextBlock
    ctb[0] = ’x’; // error!—writing a const TextBlock 

    There are two prevailing notions: bitwise constness (also known as physical constness) and logical constness.

    The bitwise const camp believes that a member function is const if and only if it doesn't modify any of the object's data members (excluding those that are static), i.e., if it doesn't modify any of the bits inside the object.

    Unfortunately, many member functions that don't act very const pass the bitwise test.

    class CTextBlock {
    public:
    
        char& operator[](std::size_t position) const // inappropriate (but bitwise const) declaration of operator[]
        {
            return pText[position];
        }
    
    private:
        char* pText;
    };
    
    const CTextBlock cctb("Hello"); // declare constant object
    char* pc = &cctb[0]; // call the const operator[] to get a pointer to cctb's data
    *pc = 'J'; // cctb now has the value "Jello"

    This leads to the notion of logical constness. Adherents to this philosophy — and you should be among them — argue that a const member function might modify some of the bits in the object on which it's invoked, but only in ways that clients cannot detect.

    class CTextBlock {
    public:
        std::size_t length() const;
    private:
        char* pText;
        mutable std::size_t textLength; // these data members may
        mutable bool lengthIsValid; // always be modified, even in
    }; // const member functions
    
    std::size_t CTextBlock::length() const
    {
        if (!lengthIsValid) {
            textLength = std::strlen(pText); // now fine
            lengthIsValid = true; // also fine
        }
        return textLength;
    }

    Having the non-const operator[] call the const version is a safe way to avoid code duplication, even though it requires a cast. 

    class TextBlock {
    public:
        //...
        const char& operator[](std::size_t position) const // same as before
        {
            //...
            //...
            //...
            return text[position];
        }
        char& operator[](std::size_t position) // now just calls const op[]
        {
            return const_cast<char&>(static_cast<const TextBlock&>(*this)[position]); // cast away const on op[]’s return type add const to *this’s type call const version of op[]
        }
        //...
    };
  • 相关阅读:
    Listbox与dataGridView的获取鼠标点击事件的区别!!!
    鼠标点击单元格显示在相应文本框中的方法(单元格事件)
    岁月不停~~
    中小学信息学奥林匹克竞赛-理论知识考点--输入输出设备
    中小学信息学奥林匹克竞赛-理论知识考点--计算机组成
    中小学信息学奥林匹克竞赛-理论知识考点--存储容量
    中小学信息学奥林匹克竞赛-理论知识考点--ASCII
    中小学信息学奥林匹克竞赛-理论知识考点--二进制
    scrapy install
    写出输出结果
  • 原文地址:https://www.cnblogs.com/zoneofmine/p/14917613.html
Copyright © 2011-2022 走看看