const关键字
经常会在程序中看到const关键字,const是constant的缩写,意为不变。
const在C++中可以用来修饰内置类型变量、自定义对象、成员函数、返回值、函数参数
1、const修饰普通类型变量
const int x = 7;
int y = x; //正确定义并赋值
x = 5; //错误,x为const类型,即常量,不允许修改x
**2、const修饰指针变量 ** (左定值,右定向)
①const修饰指针指向的内容,则内容不可变。即让指针指向一个常量对象,这样可以防止指针来修改所指向的值。
②const修饰指针本身,防止改变指针指向的位置。
例如:
int age = 27;
const int * p = &age; //const在*的左侧,左定值
//属于第一种情况,该声明指出p指向一个const int(这里为27),因此不能使用p来修改这个值,换句话说*p的值为const,不能被修改。
*p += 1; //invalid
cin >> *p; //invalid
以上指针p的声明并不意味着它指向的值实际上就是一个常量,而只是意味着对p而言,这个值是常量。
再看第二种情况,const修饰指针:
int age = 18;
int* const p = &age; //const在*的右侧,右定向
*p = 17; //正确
int age2 = 27;
p = &age2; //error const指针p,其指向的地址不能改变,但是内容可以改变。
另外需要注意:
const float money = 9.8;
const float *pm = &money; //valid
const float fee = 5.7;
float *pf = &fee; //invalid
//将fee的地址赋给pf,说明可以使用pf来修改fee的值,这使得fee的const状态很荒谬
3、const修饰参数传递 只读
const修饰函数参数主要有:
①值传递的const修饰传递,一般这种不需要const修饰,因为值传递时函数会自动产生临时变量来赋值实参值。
#include<iostream>
using namespace std;
void printValue(const int a)
{
cout<<a;
// ++a; 错误,a的值不能被改变
}
int main()
{
printValue(8);
system("pause");
return 0;
}
②当const参数为指针时,可以防止指针被意外篡改
#include<iostream>
using namespace std;
void printValue(int *const a)
{
cout<<*a<<" ";
*a = 9;
}
int main()
{
int a = 8;
printValue(&a);
cout<<a; // a 为 9
system("pause");
return 0;
}
③自定义类型的参数传递,需要临时对象复制参数,对于临时对象的构造,需要调用构造函数,比较浪费时间,因此我们采取 const 外加引用传递的方法。
并且对于一般的 int、double 等内置类型,我们不采用引用的传递方式。
#include<iostream>
using namespace std;
class Test
{
public:
Test(){}
Test(int _m):_cm(_m){}
int get_cm()const
{
return _cm;
}
private:
int _cm;
};
void print(const Test& _tt)
{
cout<<_tt.get_cm();
}
int main(void)
{
Test t(8);
print(t);
system("pause");
return 0;
}
4、const修饰函数返回值
①const 修饰内置类型的返回值,修饰与不修饰返回值作用一样。
#include<iostream>
using namespace std;
const int returnV1()
{
return 1;
}
int returnV2()
{
return 0;
}
int main(void)
{
int m = returnV1();
int n = returnV2();
cout << m << " " << n << endl;
system("pause");
return 0;
}
② const 修饰自定义类型的作为返回值,此时返回的值不能作为左值使用,既不能被赋值,也不能被修改。
③const 修饰返回的指针或者引用。
5、const修饰类成员函数
const 修饰类成员函数,是为了防止成员函数修改被调用对象的值,如果我们不想修改一个调用对象的值,所有的成员函数都应当声明为 const 成员函数。
**注意:**const 关键字不能与 static 关键字同时使用,因为 static 关键字修饰静态成员函数,静态成员函数不含有 this 指针,即不能实例化,const 成员函数必须具体到某一实例。
下面的 get_cm()const; 函数用到了 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 print(const Test& _tt)
{
cout<<_tt.get_cm();
}
int main()
{
Test t(8);
print(t);
system("pause");
return 0;
}
如果 get_cm() 去掉 const 修饰,则 print传递的 const _tt 即使没有改变对象的值,编译器也认为函数会改变对象的值,所以我们尽量按照要求将所有的不需要改变对象内容的函数都作为 const 成员函数。
如果有个成员函数想修改对象中的某一个成员怎么办,此时可以使用 mutable 关键字修饰这个成员,mutable 的意思也是易变的,容易改变的意思,被 mutable 关键字修饰的成员可以处于不断变化中,如下:
#include<iostream>
using namespace std;
class Test
{
public:
Test(int _m,int _t):_cm(_m),_ct(_t){}
void Kf()const
{
++_cm; // 错误
++_ct; // 正确
}
private:
int _cm;
mutable int _ct;
};
int main(void)
{
Test t(8,7);
return 0;
}
原文https://www.cnblogs.com/Forever-Kenlen-Ja/p/3776991.html
参考:C++ primer plus