1、简介
const是C/C++中的一个关键字,是一个类型限定符,const为constant的缩写,含义为不变的,不易改变的,使用该关键字能限定一个变量不允许改变,产生静态作用,在一定程度上能提高程序的安全性和可靠性。
2、const修饰普通类型变量
const int n = 1; //const类型对象 int m = n; //正确 n = 3; //错误,n为const限定
n被定义为一个常量,可以将n的值赋给m,但是不能给n再次赋值,n被编译器认为是一个常量,其值不允许再次修改。
int x = 2; //无const限定类型对象 const int *p = &x; //const限定类型对象 *p = 3; //错误,*p的类型为const限定
*p被限定为const类型,不能够再次赋值。
3、const修饰指针变量
const关键字修饰指针变量具有以下三种情况:
- const修饰指针指向的内容,该内容为不可变量;
- const修饰指针,该指针为不可变量;
- const修饰指针和指针指向的内容,该指针和指针指向的内容都为不可变量。
对于第一种情况,示例如下:
const int *p = 1;
p为int类型指针变量,其所指向的内容1不可改变,简称左定值,由于const位于*号的左边。
对于第二种情况,示例如下:
int a = 1; int * const p = &a; *p = 2; //正确 int b = 2; p = &b; //错误
int类型指针变量p被限定为const,因此p指向的内存地址不能够改变,但是内容可以被改变,简称右定向,因为const位于*号的右边。
对于第三种情况,则是第一种情况和第二种情况的组合,示例如下:
int a = 1; const int * const p = &a;
int类型指针变量p所指向的内容以及指向都已经固定,为不可变量。
对于上面的三种情况,根据const位于*号位置的不同,简单记忆为:左定值,右定向,const修饰不变量。
4、const修饰函数参数
const修饰函数参数大致可以分为三种情况:
第一种情况为,值传递的const修饰传递,这种情况一般不需要const修饰,因为函数会自动产生临时变量复制实参值,示例如下:
#include <iostream> using namespace std; void fun(const int a) { cout << a; //a++; //错误,a不能改变 } int main (void) { fun(1); return 0; }
第二种情况为,const参数为指针时,能够防止指针被意外篡改,示例如下:
#include <iostream> using namespace std; void fun(int *const p) { cout << *p << " "; *p = 2; } int main(void) { int a = 1; fun(&a); cout << a; //a为2 return 0; }
第三种情况为,自定义数据类型的参数传递,需要临时对象复制参数,对于临时对象的构造,需要调用构造函数,比较浪费时间,可以采用const外加引用传递的方式,示例如下:
#include <iostream> using namespace std; class Test { public: Test() {} Test(int _m):_cm(_m) {} int get_cm() const { return _cm; } private: int _cm; }; void fun(const Test& _tt) { cout << _tt.get_cm(); } int main(void) { Test t(2); fun(t); //结果输出2 return 0; }
5、const修饰函数返回值
对于const修饰返回值,主要分三种情况,如下:
第一种情况为,const修饰内置类型的返回值,修饰与不修饰返回值作用一样,示例如下:
#include <iostream> using namespace std; const int fun1(void) { return 1; } int fun2(void) { return 2; } int main(void) { int a = fun1(); int b = fun2(); cout << a << " " << b; return 0; }
第二种情况为,const修饰自定义类型作为返回值,此时返回的值不能作为左值使用,不能被赋值,也不能被修改。
第三种情况为,const修饰返回的指针或者引用,是否返回一个const指向的指针,取决于我们想让用户干什么。
6、const修饰类成员函数
使用const修饰类成员函数,其目的是为了防止成员函数修改被调用对象的值,如果我们不想修改一个调用对象的值,那么,对象内的所有成员函数都应当声明为const成员函数,示例如下:
#include <iostream> using namespace std; class Test { public: Test() {} Test(int _m):_cm(_m) {} int get_cm() const //const修饰成员函数 { return _cm; } private: int _cm; }; void fun(const Test& _tt) { cout << _tt.get_cm(); } int main(void) { Test t(2); fun(t); return 0; }
Test类中的成员函数get_cm使用了const进行修饰,如果去掉了const修饰的话,函数fun()传递的const _tt即使没有改变对象的值,编译器也认为函数会改变对象的值,因此,一般按照要求将所有的不需要改变对象内容的成员函数使用const进行修饰。
当有成员函数想要修改对象中的某个成员时,可以使用关键字mutable修饰该成员,被mutable修饰的成员可以处于不断变化,如下例子:
#include <iostream> using namespace std; class Test { public: Test() {} Test(int _m, int _n):_cm(_m),_cn(_n) {} void func() const { _cm++; //错误 _cn++; //正确 } private: int _cm; mutable int _cn; }; int main(void) { Test t(1, 2); return 0; }
Test类中的func()成员函数被限定为const类型,在func()成员函数中修改成员_cm和_cn的值,使用_cm++修改_cm的值将会报错,因为_cm成员并没有使用mutable关键字进行修饰。
原文地址:
https://www.cnblogs.com/Forever-Kenlen-Ja/p/3776991.html