c++:const 操作小结
一 const直接修饰一个非指针变量并进行初始化,则该变量不能被修改
const int a =100 ;
结果:
1 变量a不能直接被修改。类似 a=101;这样的语句不能通过编译
2 取地址操作也需要加const 修饰符,
const int *b=&a ;
否则编译失败.失败信息:'initializing' : cannot convert from 'const int *__w64 ' to 'int *'。
3 引用操作符定义别名也需要加const修饰符,否则编译失败
const int &c=a ;
否则编译失败,失败信息: cannot convert from 'const int' to 'int &' d
二 const定义指针变量共有两种情况。
1 const修饰指针,限定其所指向的内容不可修改
int val=100 ;
const int * ptr=&val ; //*ptr 为只读
*ptr=101 ; //编译错误,错误信息: l-value specifies const object
2 const修饰指针,限定该指针不可修改
int val1=100 ;
int val2=200 ;
int * const ptr=&val1 ; //ptr为只读
ptr=&val2 ;//编译错误,错误信息:l-value specifies const object
3 直接对常指针初始化 const int * a=new int(10) ;
int *b=a; //编译错误,不能把常指针赋给一个非常量指针
const int *b=a; //编译成功。 可以使用常指针对另一个常指针进行初始化。
int c=*a ; c=100 ; //编译成功。因为其进行的传值操作,const 对c没有限制作用.
三 函数返回值为const 类型,(不包含返回引用或者返回地址即返回 const type,而不是const type & 或者const type *)
一句话,其规则就是把这个函数当作一个常量标志符来看待。例如
const int abc() ; //函数声明
//int &b=abc() ;//编译错误
const int a=abc() ; //编译正确
const int &b=abc() ; //编译正确
四 函数为返回常量地址(函数返回值为const type*类型)
const int* abc() ; //函数声明,
等同于函数声明: int * const abc()
int * a=abc() ; //编译错误:'initializing' : cannot convert from 'const int *' to 'int *'
const int*b=abc() ; //编译通过
const int*b=abc() ; //编译通过
(*abc()) ++ ; //编译失败,因为(*abc())是对常量取值,而(*abc())会自动转换为常量: you cannot assign to a variable that is const
const int c=*abc() ;//编译通过,因为对变量‘c’是获得了*abc()的一个拷贝,const修饰符对c不起作用了。
五 函数为返回常量引用(函数返回值为const type &类型)
const int& func() ; //函数声明
const int& a=func() ; // 编译通过
int a=func() ; //编译通过,本质为传值
int& a=func() ; //编译失败,错误消息: cannot convert from 'const int' to 'int &'
六 关于函数返回值为函数作用域内部的局部变量或者局部地址的问题:
/*声明并定义函数,返回其内部变量的地址或者引用*/
int * func1 ()
{
int a=100 ;
return &a ; //a为临时变量,函数返回临时变量地址
}
int & func2()
{
int a=100 ;
return a; //函数返回临时变量引用
}
//函数调用
int *a=func1() ;
int b=func2() ;
以上代码不会编译出错,而会引发一个警告:returning address of local variable or temporary。
当你把一个函数体内的临时变量的地址或者引用作为返回值返回时, 编译器会创建另外一份该临时变量的拷贝,因为以前那个临时变量已经在函数执行完毕时出栈而不可用了。当然这样会有很大的危险性。