Const关键字
const 是constant 的缩写,本意是不变的,不易改变的意思。在 C++ 中是用来修饰内置类型变量,自定义对象,成员函数,返回值,函数参数。
1.用const修饰成员变量
const int num = 111;
num = 222;
- 指针变量
只有一个const时,如果const位于*的左侧,表示指针所指的数据是常量,不能通过该指针修改实际数据,指针本身是变量,可以指向其他内存单元。
int num1 = 123;
int num2 = 456;
const int * ptr_num1 = &num1;
int const * ptr_num2 = &num1;
ptr_num1 = &num2;
*ptr_num1 = 789;
只有一个const时,如果const位于*的右侧,表示指针本身是常量,不能指向其他内存单元,指针所指的数据可以修改。
int num1 = 123;
int* const ptr_num1 = &num1;
*ptr_num1 = 456;
ptr_num1 = &num2;
有两个const,位于*左右两侧,表示指针本身和指针所指向的数据都是常量,不能修改。
int num1 = 123;
int num2 = 456;
const int* const ptr_num = &num1;
ptr_num = &num2;
*ptr_num = num2;
2.用const修饰函数的参数
如果参数是作输出用的,那么不论它是什么数据类型,也不论它采用“指针传递”还是“引用传递”,都不能加const 修饰,否则该参数将失去输出功能。所以const 只能修饰输入参数。
- 输入参数采用“指针传递”
加const 修饰可以防止意外地改动该指针,起到保护作用
void StringCopy(char* strA, const char* strB)
{
}
- 输入参数采用“值传递”
值传递,传递的是实际参数的一个副本,此时加const与修饰变量时的性质一致
void TestFun1(const int value)
{
value = 123;
}
void TestFun2(const A a)
{
a = A();
}
由于函数将自动产生临时变量用于复制该参数,该输入参数无需保护,所以一般不加const 修饰。所以上述函数一般写作如下:
void TestFun1(int value);
void TestFun2(A a);
- 输入参数采用“引用传递”
对于非内部数据类型的参数而言,例如:void TestFun2(A a) 这样声明的函数效率比较低。因为函数体内将产生A 类型的临时复制对象,而临时对象的构造、复制、析构过程都将消耗时间。为了提高效率,可以将函数声明改为void TestFun3(A& a),因为引用传递,对形参的操作等同于对实参的操作,即传递的不会是实参的副本,而就是实参,只是起了个别名而已。
void TestFun3(const A& a)
{
}
3.用const修饰函数的返回值
- 返回值采用“指针传递”
那么函数返回值(即指针)的内容不能被修改,该返回值只能被赋给加const 修饰的同类型指针。
const int * TestFun4(int& num)
{
return #
}
int num = 15;
int * ptr_num = TestFun4(num);
const int * ptr_num = TestFun4(num);
- 返回值采用“值传递”
由于函数会把返回值复制到外部临时的存储单元中,此时加const 修饰没有任何价值。
const int TestFun5();
const A TestFun6();
int TestFun5();
A TestFun6();
- 返回值采用“引用传递”
如果返回值不是内部数据类型,那么为了提升效率,可以将函数A TestFun6() 改写为const A & TestFun6()。但是值得注意的是,此时一定要搞清楚函数究竟是想返回一个对象的“拷贝”还是仅返回“别名”就可以了。如果函数可以返回对象,也可以返回对象的引用,应该首选对象的引用,因为这样效率高。
const A & TestFun7(A & a)
{
return a;
}
const A & TestFun8()
{
A a;
return a;
}
4.用const修饰成员函数
任何不会修改数据成员的函数都应该声明为const 类型。
class TestClass
{
public:
int value;
int GetValue() const { return value; }
void ModifyValue() const
{
value = 123;
}
}
注意:const 关键字不能与 static 关键字同时使用,因为 static 关键字修饰静态成员函数,静态成员函数不含有 this 指针,即不能实例化,const 成员函数必须具体到某一实例。 使用mutable和volatile关键字修改的变量可以突破const限制。C++中的mutable和volatile
|