C++ const使用总结

参考文章C/C++中const关键字详解 关于C++ const 的全面总结

  1. 常量

    const限制了常量的使用方式,声明时必须进行初始化。C中,const定义的变量是全局的,C++中视声明位置而定。

    将const改为外部连接,作用于扩大至全局,编译时会分配内存,并且可以不进行初始化,在程序其他地方进行了定义

  2. 指针和常量

    使用指针时,涉及到两个对象:该指针本身(地址)和它所指向的对象(具体数值)。将一个指针的声明用const,将使对象(具体数值)而不是使该指针(地址)成为常量;用const*,将指针本身(地址)而不是被被向的对象(具体数值)声明为常量。

    char *const pc 表示指针pc不能指向别的字符串,只能指向初始地址(即地址固定),但是可以修改其指向的字符串的内容;

    char const *pc1 表示pc1的内容不可以改变(即数值固定),但是pc指针可以指向其他的字符串

    const char *pc2 作用同char const *pc1

    允许把非const对象的指针赋给指向cosnt对象的指针;不允许把一个const对象的地址赋给一个普通的、非cosnt对象的指针

    const char* const pContent 表示指针和指针所指向的内容都不可变

    还有其他区别方法: - const位于的左侧,则const是用来修饰指针所指向的变量,即指针指向为常量 - const位于的右侧,则const修饰指针本身,则指针本身是常量

  3. const修饰函数传入参数

    将函数传入参数声明为const,以指明使用这种参数仅仅是为了效率原因,而不让调用函数修改对象的值;同理,将指针参数声明为const,函数将不能修改由这个参数所指向的对象

    void Fun( const A*in) 使用指针型传入参数; void Fun(const A &in)使用引用型传入参数

  4. 修饰函数返回值

    可以阻止用户修改返回值,返回值也要相应的赋给一个常量或常指针

    const int fun1() 函数返回的值为常量;const int *fun2() 调用时,为const int *pValue = fun2(),即指针内容不变;int* const fun3()调用时,为int* const pValue = fun2(),表示指针地址不变

    一般情况下,函数的返回值为某个对象时,将其声明为const时,多用于操作符的重载。不建议用const修饰,函数返回值类型为某个对象或对某个对象引用

  5. 类相关

    • const修饰成员变量:不能被修改,同时只能在初始化列表中赋值

    • const修饰成员函数:该成员好桉树不能修改类中任何非const成员函数,也不能调用类中任何非const成员函数
      • const成员函数不被允许修改其所在对象的任何一个数据成员
      • const成员函数能够访问对象的const成员,而其他成员函数不可以
    • const修饰类对象、对象指针、对象引用
      • const修饰类对象表示该对象为常量对象,其中的任何成员都不能被修改。对于对象指针和对象引用相同
      • const对象的任何非const成员函数都不能被调用,因为任何非const成员函数会有修改成员变量的企图

    const对象只能访问cosnt成员函数,而非const对象可以访问任意的成员函数,包括const成员函数;cosnt对象的成员是不能修改的,而通过指针维护的对象确实可以修改;const成员函数不可以修改对象的数据,不管对象是否具有const性质

补充

  1. const通常是限制其定义的变量不能被修改,但是通常情况下,可以通过另外的方式去修改它的值。即不能直接修改,但是可以间接地对其修改

  2. 常量指针和指针常量比较容易混淆。const只对其左边的东西起作用;但是当const为最左边的修饰符,其才会对右边的东西起作用

    const int m1 = new int(10); // m1为常量指针,不能修改m1指向的内容,但是可修改m1的指针 int const m2 = new int(20); // m2为指针常量,不能让m2指向其他的地址,但是可以修改m2指向地址所存储的数值

  3. 常量函数是对常量的一个拓展,确保了C++中类的封装性。为了防止数据成员被非法访问,将类成员函数分为两类:一类是常量成员函数,一类是非常量成员函数。在函数的声明后加上const,则该函数为常量函数,编译器不允许其修改类的数据成员

常量成员函数,不能修改类中的数据成员

常量对象是不希望其数据成员被修改,而常量成员函数是不能修改数据成员

  • 非常量对象可以调用常量函数(不修改数据成员)
  • 非常量对象允许调用非常量函数(普通情况)
  • 常量对象只能调用常量函数(常量函数不希望修改常量对象状态,而常量函数正好不修改对象状态)
  • 常量对象不能调用非常量函数(非常量函数存在修改常量对象状态的可能,不能保证对象不被修改)

class A { const int size;}const数据成员在某个对象生存期内是常量,对整个类为可变的,不能在类声明中初始化const数据成员

const数据成员的初始化,只能在类的构造函数的初始化列表中进行。在整个类中都恒定的常量,应该用类的枚举常量实现;枚举常量不会占用对象的存储空间,在编译时被全部求值

  1. 常量返回值

函数常常会返回一个地址或者引用。调用所得到的返回的地址或引用后,即可修改所指向或者代表的对象。**如果不希望修改函数返回后的内容,则可限定函数返回常量

将const类型转化为非const类型的方法

采用const_cast进行转换,用法const_cast <type_id> (expression)用来修改类型的const或volatile属性

建议

  • 在参数中使用const应该使用引用或指针,而不是一般对象实例
  • const在成员函数中的三种用法(参数、返回值、函数)
  • 不要随便将函数的返回值类型定位const
  • 除了重载操作符外,一般不要将返回值类型定为对某个对象的const引用
  • 任何不会修改数据成员的函数都应该声明为const