今天我给大家详细地讲一讲C++中const关键字的应用
1> 指向const对象的指针
格式:const int *cpt;
“自以为指向const的指针”,其本身不是const。
2> const指针
格式:int errNumb = 0;
int *const curErr = &errNumb;
指向int型对象的const指针,其本身是const,必须初始化。
3> 指向const对象的const指针
格式:const int E = 3;
const double *const PE = &E;
既不能修改PE所指向的对象的值,也不能修改该指针的指向。
4> typedef string *pstring
可以把上述语句理解为typedef (string *) pstring
定义const对象是建议把const写在类型的后面,如
const int i = 3; //不建议
int const i = 3; //建议
观察以下语句组:
typedef string *pstring (1)
const pstring cstr; (2)
如上所诉可知(2)等价于string *const cstr,所以cstr是一个const指针,而不是const string *cstr。
5> 在函数调用时如果形参被声明为非引用非const的形参,则可给该函数传递const实参也可传递非const实参
如果形参被声明为非引用的const形参,可以给该函数传递const实参也可以传递非const实参,只是此时不
能修改实参的副本的值而已。所以具有const形参或非const形参的函数并无区别,这种情况下不能构成重载。
6> 把函数的形参声明为const的引用可以避免对象的复制
如:bool isShorter(const string &s1, const string &s2)
{
return s1.size()<s2.size();
}
7> 非const引用形参只能与完全相同的非const对象关联
int incr(int &val)
{
return ++val;
}
int main()
{
short v1 = 0;
int v2 = incr(v1); //error
return 0;
}
8> 应该把不修改相应实参的形参定义为const引用,否则将限制该函数的使用,下面代码将产生编译错误
string::size_type find_char(string &s, char c)
{
while(i!=s.size()&&s[i]!=c) ++i;
return i;
}
int main()
{
find_char("Hello World", 'o') //error
return 0;
}
错误的原因:虽然字符串字面值传递给函数可以产生局部对象,但是这里形参被声明为引用,必须引用
一个已存在的对象,所以上述代码才会导致编译错误。
9> 仅当形参是引用或指针时,形参是否为const才有重载现象
fun1: Record lookup(Account &);
fun2: Record lookup(const Account &);
const Account a(0);
Account b;
lookup(a); //call lookup(const Account &)
lookup(b); //call lookup(Account &)
函数fun2既可以接受a,也可以接受b,但此时,b匹配fun1
注意:不能基于指针本身是否为const来实现函数的重载
f(int *);
f(int *const);
以上两个函数无法构成重载。