zoukankan      html  css  js  c++  java
  • Effective C++ 条款3 尽可能用const

    1. const可被施加于任何作用域内的对象,函数参数,函数返回类型,成员函数本体.用const修饰指针,如果const出现在*之前,表明指针不能更改所指向的对象的内容,如果const出现在*之后,表明指针只能指向同一块内存.另外int const*p和const int*p含义相同.如果对象成员有普通指针,那么构造该类的一个const对象时,const修饰使得该指针只能指向同一块内存,但指针指向的内容可以改变.

    2. 将某些东西声明为const可以帮助编译器侦测出错误用法.

    3. 编译器强制实行bitwise constness(又称physical constness,物理上的常量性,即成员函数不更改对象的任何一个bit时才可以说是const),例如:

    class TextBlock{
    public:
        ...
        char& operator [](std::size_t position) const{
            return pText[position];
        }
    private:
        char* pText;
    }
    View Code

        编译器认定它是bitwise constness的,但是它却允许以下代码的存在:

    const CTxetBlock cctb("Hello");
    char* pc=&cctb[0];
    *pc='J';
    View Code

        这是由于只有pText是cctb的一部分,其指向的内存并不属于cctb

        程序员编写程序时应该使用conceptual constness(概念上的常量性或logical constness,逻辑上的常量性,即一个const成员函数可以处理它所修改的对象的某些bits,但只有在客户端侦测不出的情况下才得如此),例如对于某些特殊类,其中的某些成员的值注定是要改变的,因此可以用mutual关键字修饰,从而实现即使对象被设定为const,其特定成员的值仍然可以改变的效果.此时该类符合conceptual constness而不符合bitwise constness.

    4. 如果参数是引用,可以基于参数是否为const实现函数重载(也可以基于指针是否为const实现函数重载),特殊的,对于成员函数,因为它存在一个隐含的this指针参数,因而可以基于函数是否为const实现重载.

    5. 当const和non-const成员函数拥有重复的实现时,令non-const版本调用const版本可避免代码重复,例如对于以下实现:

    class TextBlock{
    public:
        ...
        const char& operator[](std::position) const{
            ...
            return text[position];
        }
        char& operator[](std::position) {
            ...
            return text[position];
        }
    private:
        std::string text;
    }
    View Code

        通过令non-const版本调用const版本如下:

    class TextBlock{
    public:
        ...
        const char& operator[](std::size_t position) const{
            ...
            return text[position];
        }
        char operator[](std::size_t position){
            return const_cast<char&>(
                 static_cast<const TextBlock&>(*this)[position]);
        }
        ...
    };
    View Code

        可以看出,经过了两次类型转换,第一次通过static_cast将*this转为const TextBlock&以确保调用的是operator[]的const版本,否则会调用非const版本导致递归调用造成栈溢出;第二次通过const_cast去掉const版本的opsrator[]返回的const char&的const特性以与函数的返回类型相匹配.

        注意,不能用const版本调用non-const版本,因为non-const版本极有可能改变对象的值,这与const版本的const特性相矛盾.

    6.注:对于const_cast的行为之前存在一些误解,对于以下代码:

    #include<iostream>
    using std::cout;
    using std::endl;
    int main(){
        const int a = 5;
        int& rta = const_cast < int&>(a) ;
        rta = 6;
        cout << "a: " << a << "    rtr: " << rta << endl;
        cout << "&a: " << &a << "     &rta: " << &rta;
        system("pause");
        return 0;
    }
    View Code

        输出结果如下:

        可见虽然const_cast表面上改变了变量的const性质,但a的值实际上还是没有改变(编译器仍然背着我们干了不少事),所以const_cast的实际用途并不是改变const对象的值,而是"暂时"去除对象的const属性使其可以作为参数传入非const函数,企图通过const_cast改变const对象的值可能会导致未预料的结果.因此个人认为5中的第二段代码(出自Effective C++ “条款3  尽可能用const”)存在一些错误,如有错误欢迎批评指正!

  • 相关阅读:
    《2019面向对象程序设计(java)课程学习进度条》
    201871010126 王亚涛 实验四 团队作业1:软件研发团队组建
    201871010126 王亚涛 实验三 结对项目—《D{0-1}KP 实例数据集算法实验平台》项目报告
    201871010126-王亚涛 实验二 个人项目—0-1背包问题项目报告
    20187101026-王亚涛 实验一软件工程准备-软件工程初步学习
    201871010126 王亚涛《面向对象程序设计(Java)》 课程学习总结
    201871010126 王亚涛 《面向对象程序设计 (Java)》第十七周学习总结
    201871010126 王亚涛 《面向对象程序设计 (Java)》第十六周学习总结
    201871010126 王亚涛 《面向对象程序设计 Java》 第十五周学习总结
    201871010126 王亚涛 《面向对象程序设计JAVA》第十四周学习总结
  • 原文地址:https://www.cnblogs.com/reasno/p/4737709.html
Copyright © 2011-2022 走看看