C++ const

1 最基本的用法:
A) const int a=100; b的内容不变,b只能是100也就是声明一个int类型的常量(#define b =100)
int const b=100; //和上面作用一样

B)const指针和引用一般用在函数的参数中
int* m = &a; //出错,常量只能用常指针,如下
int c= 1;const int*pc = &c;//常指针可指向常量

const int* pa = &a; //指针指向的内容为常量(就是b的值不变)
int const *a = &b; //指针指向的内容为常量(就是b的值不变)*p=3//error
int* const a = &b; //指针为常量,不能更改指针了如 a++但可以改值*p=3;

从这可以看出const放在左侧修饰的是指针的内容,const放在右侧修饰的是指针
本身,呵呵这种记忆方法好

C)const引用的用法和指针一样
int const & a=b; 和指针一样
const int& a=b; 和指针一样
但没有 int& const a=b 的用法因为引用不能做移位运算,但只是出个warning

D)const int* const a = &b; //综合应用,一般用来传递多维的数组
类如:char* init[] = {“Paris”,”in the”,”Spring”};
void fun(const int* const a){}
fun(init)//保护参数不被修改

E)int A(int)const; //是常函数,只能用在类中,调用它的对象不能改改变成员值

const int A(); //返回的是常量,所以必须这么调用 const int a=A();
int A(const int); //参数不能改值,可用在任意函数
int A(const int*);
int height() const;//常函数只能由常函数调用
int max(int,int) const;
int Max = max(height(),height()); //其中max为常函数

2 const 和引用联合使用的时候要注意

A) 强传const对象可能导致无定义行为

对于优化做的比较好的编译器,代码 const int i = 1;
当后面用到变量 i 的时候,编译器会优化掉对 i 的存取,而直接使用立即数 1

const int i = 1; 

*(const_cast<int*>(&i)) = 2;
cout << *(int*)&i << endl;
cout << i << endl; 

所以,对 const 对象做 const_cast 可能导致无定义行为
B)不能将const修饰的任何对象、引用和指针作为赋值表达式的左值。

const int cx=100;
const int & rcx=cx;
const int * pcx=&cx;
cx=200; //error
rcx=200; //error
*pcx=200; //error 

C).const类型的对象不能直接被non-const类型的别名所引用。
(1)不能将const类型的对象传递给non-const类型的引用。
const int cx=100;
int & rx=cx; //error
D)不能将const类型的实参传递给形参为non-const类型引用的函数。
void f(int a)
{
}
void g(int & ra)
{
}
const int cx=100;
f(cx); //ok
g(cx); //error
E)不能将const类型的对象作为non-const类型引用的函数返回值。
int & f(const int & rca)
{
return rca; //error
}
int x=100;
f(x);

3.可以使用const类型别名引用non-const对象。此时通过const引用不能修改对象,但对象可以通过non-const引用被修改。
int x=100;
int & rx=x;
const int & rcx=x; //ok
x=200;
rx=200;
rcx=200; //error

4.若函数的返回值为内建类型或是指针,则该返回值自动成为const性质。但自定义类型则为non-constint f() //相当于返回const int
{
return 100;
}
int * g(int & ra) //相当于返回int * const
{
return &ra;
}
class CTest
{
int n;
public:
CTest(int n){this->n=n;}
};
CTest h() //返回的就是CTest
{
return CTest(200);
}

f()=200; //error

int x=100;
int y=200;
int * px=&x;
g(y)=px; //error
g(y)=x; //ok,从这点可以看出g()返回的不是const int

CTest t(100);
h()=t; //ok,但却是完全错误的、危险的做法
//所以h()的正确写法是返回const CTest. 常函数的调用是这样的:常量对象只能调用常成员函数,非常量对象即可以调常成员函数,也可以调一般成员函数,但当某个函数有const和非const两个版本时,const对象调const版本,非const对象调非const版本
例:

class A
{
public:
int & GetData(){return data;}
const int & GetData()const {return data;}
private:
int data;
} 
A a;
a.GetData();//调用int & GetData(){return data;}
//但如果没有这个函数,也可以调用const int & GetData()const 
const A const_a;
const_a.GetData();//调用const int & GetData()const {return data;}
常函数只能调常函数,也是由于这个原因




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值