zoukankan      html  css  js  c++  java
  • 条款03:尽可能使用const

    1、为什么尽可能使用const?
    const指定语义约束,即某个对象不应该被改变,并且编译器会强制执行这条约束。如果某个对象确实不应该被改变,那么我们就应该将其生命为const,这样一来,如果违背了这个约束,编译器将帮助我们检测出来。

    2、界定常量指针和指向常量的指针

    const Type * pt;//(1)
    Type const *pt;//(2)
    Type* const pt;//(3)
    

    (1)和 (2) 表达的意思是一样的,即指向常量的指针。而(3) 表示常量指针。也就是二者的界定点在与constzai星号前还是后,跟类型前后无关。

    3、迭代器与指针的关系
    迭代器是由指针塑模出来的,因此迭代器的作用就相当于是一个T*类型的指针,如果迭代器指向不可改变的数据:

    const std::vector<int>::iterator iter;
    

    如果表达迭代器不可改变指向(自身为const):

    std::vector<int>::const_iterator iter;
    

    4、const与函数声明式
    const的最大威力便对函数声明时的应用,在一个函数声明式内,const可以和:函数返回值、各个参数、函数自身产生关联。
    5、const 与函数返回值
    令函数返回一个常量值往往可以减少错误。
    例如:重载乘号时(*):

    const Rational operator *(const Rational& lhs,const Rational& rhs)
    Rational a,b,c;
    (a*b)=c;
    

    如果符号函数的返回值不是const的,那么执行:

    (a*b)=c;
    

    时将会导致错误,这相相当于对两个数的乘积的结果做赋值。
    再例如:

    if(a*b=c);//本来想写成a*b==c 
    

    如果a、b是内置类型,这样的结果直接就是错误的。自定义类型应该更好的内置类型兼容,因此对两个数的乘积做赋值也应该表达为非法。而将返回值设置为const就可以表达出这种非法效果,让编译器识别出来。
    6、const成员函数
    (1)const成员函数的有两个重要作用:

    • 确定哪个函数可以改变对象内容,哪个不行。让class接口更容易理解。
    • 将const作用于成员函数的目的是确认该成员函数可作用于const对象上面。 使得操纵const对象变得可能。它支撑以pass by reference-to-contst方式传递对象。而pass by reference-to-contst 正是改善C++程序效率的根本方法。实现这种传递方式的前提便是有const函数可用来处理取得(并经修饰)的const对象。

    (2)同签名的const函数与non-const成员函数的关系
    const成员函数与non-const成员函数构成重载关系,这一点非常重要。当函数传递的是一个const对象时,调用const成员函数,如果没有这样的成员函数就会报错。当函数传递的是一个non-const对象时,调用non-const成员函数,如果没有这样的成员函数就会报错。

    (3)成员函数声明为const意味着什么?
    有两个派别: 和logical constness

    • bitwise constness 派认为:成员函数只有不改变对象的任何成员变量时才被称为const。这种想法有时并不合理,因为假设定义了一个类,其中有一个指针。const函数改变指针指向时是不合法的,但是如果我们改变了指针所指向的内容,此时实际上可以说改变了一个const对象,但是编译器却识别不出来。

    • logical constness 派认为:成员函数可以改变对象的某些bits,但是只有在客户端检测不出来的时候才可以这样做。那么const函数可以改变哪些变量呢?以mutable修饰的变量。改变指针指向内容实际上编译器也识别不出来,但是客户端能检测出来,因此这不叫const函数。

    编译器执行的是bitwise constness ,但是我们在编程时,应该使用logical constness。

    (4)避免同签名 const成员函数和non-const成员函数代码重复
    有些时候,const函数和non-const的代码一样,但是一个为const函数,一个为non-const函数。如果这时分别写两个函数的话,显然造成了代码重复问题。

    这时我们应该考虑实现函数一次,但是使用它两次。也就是说,必须令其中一个调用另一个。一般使用non-const 调用const版本来避免代码重复问题,并且在充当non-const使用时,应该将函数转换为const的。不能使用const来调用non-const来解决上述问题。

  • 相关阅读:
    Flink Application Development DataStream API Execution Mode (Batch/Streaming)- Flink应用程序开发DataStream API执行模式(批/流)
    Flink Application Development DataStream API Overview
    Flink Concept Stateful Stream Processing -Flink概念有状态流处理
    Hdfs原理
    Leetcode 763 划分字母区间
    406. 根据身高重建队列
    贝叶斯统计概要(待修改)
    蒙特卡罗方法
    马尔科夫链蒙特卡罗方法(MCMC)
    Leetcode452. 用最小的箭引爆气球
  • 原文地址:https://www.cnblogs.com/lasnitch/p/12764254.html
Copyright © 2011-2022 走看看