C++ const 引用 指针答疑

常变量 const int a

常引用 const int &a

常指针 const int *a

const * int a

用法1:常量
    取代了C中的宏定义,声明时必须进行初始化(!c++类中则不然)。const限制了常量的使用方式,并没有描述常量应该如何分配。如果编译器知道了某const的所有使用,它甚至可以不为该const分配空间。最简单的常见情况就是常量的值在编译时已知,而且不需要分配存储。―《C++ Program Language》
    用const声明的变量虽然增加了分配空间,但是可以保证类型安全。
    C标准中,const定义的常量是全局的,C++中视声明位置而定。

用法2:指针和常量
    使用指针时涉及到两个对象:该指针本身和被它所指的对象将一个指针的声明用const“预先固定”将使那个对象而不是使这个指针成为常量要将指针本身而不是被指对象声明为常量,必须使用声明运算符*const
    所以出现在 * 之前的const是作为基础类型的一部分:
char *const cp; //到char的const指针
char const *pc1; //到const char的指针
const char *pc2; //到const char的指针(后两个声明是等同的)
    从右向左读的记忆方式:
cp is a const pointer to char. 故pc不能指向别的字符串,但可以修改其指向的字符串的内容
pc2 is a pointer to const char. 故*pc2的内容不可以改变,但pc2可以指向别的字符串

且注意:允许把非 const 对象的地址赋给指向 const 对象的指针,不允许把一个 const 对象的地址赋给一个普通的、非 const 对象的指针。

用法3:const修饰函数传入参数
    将函数传入参数声明为const,以指明使用这种参数仅仅是为了效率的原因,而不是想让调用函数能够修改对象的值。同理,将指针参数声明为const,函数将不修改由这个参数所指的对象。
    通常修饰指针参数和引用参数:
void Fun( const A *in); //修饰指针型传入参数
void Fun(const A &in); //修饰引用型传入参数

引用&的作用:例如a=&b,那么表示a是b的别名,此时a和b的地址相同。在子函数中调用时,形参的改变就是实参的改变,不像C中需要用到指针来实现。

子函数调用时,并没有申请一个空间来存放形参b,也不用将实参a的值传给形参b,因此使程序运行更简化。

参考自https://blog.csdn.net/tom__chen/article/details/22206459

用法4:修饰函数返回值
    可以阻止用户修改返回值。返回值也要相应的付给一个常量或常指针。

用法5:const修饰成员函数(c++特性)
const对象只能访问const成员函数,而非const对象可以访问任意的成员函数,包括const成员函数;
const对象的成员是不能修改的,而通过指针维护的对象确实可以修改的;
const成员函数不可以修改对象的数据,不管对象是否具有const性质。编译时以是否修改成员数据为依据进行检查。

不加引用的话,str则被复制一份,函数中对str的操作实质上是对其复制品的操作,所以即使在函数中修改了str,调用层的原str并不会被改变。
加了引用的话,传入的str即是调用层的实际参数,这样省却了复制过程,效率会有提高。但如果函数中修改了str,则原str也会改变,因为其实是同一个东西。
有时候为了追求效率,又希望避免改变原来的str,则可在引用的基础上加const修饰,这样函数中就不能再修改str的内容(否则会编译出错)

用法5:const与指针

int *ptr;
const int *ciptr;
int const *icptr;
int * const cptr;
const int * const cicptr;

上面是关于const与指针结合时的各种情况,这并不只是C++中经常遇到的问题,在C语言中也会有类似的讨论,虽然const并不是C语言中的关键字。
int * ptr 是指定义一个指向int 类型的指针ptr。
const int *ciptr 是指定义一个指向const int 类型的指针ciptr,这是const 限定的是(* ciptr),也就是对指针解引用,即const限定的就是数据本身,而非指针。所以ciptr是一个指向常int型数据的指针。
int const * icptr其实和上面的const int *ciptr是一致的因为const只是一个限定符,在int前还是后都 没有影响,他限定的仍然是(*icptr),并不是icptr,也就是icptr也是指向常int型数据的指针,也就是说在icptr这个指针看来,它指向的数据是常数,是不能改变的,但是是否真的不能改变,需要依据实际的类型的分析,只是不能通过这个指针来改变。也就是说该指针是一个自以为自己指向常量的指针。
int * const cptr 这时候我们还是结合const的位置分析,const限定的是cptr,cptr我们可以知道是一个指针,也就是说const限定的是一个指针,而不是指针指向的数据,也就是说这种定义实质上是定义一个常指针,也就是指针指向的地址是不变的,也就是cptr是不能被赋值的,不能采用这个指针指向其他的对象或者地址。但是这个地址中的数据并不是常数,是可以改变的,可以通过对*cptr进行修改。这种指针实质上也就使得指针的效果大大减小,并不常用。
const int * const cicptr 这种定义结合上面的分析我们知道是一个指向常量的常指针,也就说这个指针指向的地址是一个常地址,指针不能指向其他的对象或者地址。同时对指针cicptr来说,我指向的这个地址中的内容也是不能修改的,是一个常量,是不能修改的,但是该地址的数据能否修改还需要进行实际的分析。

参考自http://www.eepw.com.cn/article/201612/324522.htm

http://www.cnblogs.com/hustcat/archive/2009/04/11/1433549.html

猜你喜欢

转载自blog.csdn.net/weixin_38383877/article/details/84335968
今日推荐