const使用小结--带领你永久突破识别申明,定义语句的障碍



多年来一直对const不是抠的很清楚,最近看了《the c++ templates》,在图书约定中目睹了更高级的变量声明方法,才慢慢明白const的真正用法。

以前看《c++ primer》,作者告诉你怎样看一个使用到了const的语句:const int a; -- “从右向左看”。我一直没搞清楚这句话的意思,究竟怎样从右向左看呢???

在《C++ Templates》中,我看到作者对变量的声明的风格类似是这样的:
1.  int const a;
2.  int const & a;
3.  int& const a = other;
4.  int const * a;
5.  int const* &a;
6.  int const* const a;
7.    int const* cosnt& a;
8   int* const & a;
...

才有种顿悟的感觉,如果把const和右边的token结合,那么很多问题就迎刃而解了:
1.a本身作为变量被设定为const,所以a不能在改变。


2.第二句这样的申明在函数中使用:
void func(type const & value);
    const 与右边的&结合,所以这个引用是const,你没办法改这个传入引用的的值,比如value = other;这就会导致编译错误。


3.第三句这样的写法,没有实际意义,但有语义意义。
同样,const是修饰a的,那么a是不能在更改为其他变量的引用的,但是由于引用只能在初始话的时候被指定一次,所以int& const a ; 和int & a; 在实际效果上是一模一样的,无论起作为函数参数,还是变量类型。
void fun(int& const value);  == void fun(int& value);

int c = 5;
int& const d = c; == int& d = c;

4.const修饰的是*,所以这个指针所指向的东西是不能被更改的,但由于a不是const,所以可以将a指向不同的变量。
void fun(int const* a)
{
    *a = 5;        //编译错误,试图将a指向的值修改
   
    int b = 5;
    a = &b;        //ok,因为a不是常量
    *a = 10;    //同样编译错误,同上上
}

注:在这种声明中,当进入函数的时候,系统在栈上创建了一个新的指针变量,该指针变量的值被设定成传入的指针的值,所以对该指针变量的修改,不会影响传入的指针的值。

5.这种方法和上一种的实际意义基本一样,只是语义上还是不同的。a是作为引用创建的,但和上一种方法的基本一致。

6.第一个const修饰的*,代表指针指向的值不能改,第二个const修饰的a,说不a的值也不能改,这种申明应该是比较常用的,这样声明以后,你传入的指针值,你只能获取这个指针所指向的对象的成员变量或调用函数等等,但是却不能更改任何东西,甚至不能将a重新指定到另一个地址。

7.实际意义等同于6,只是a是作为引用创建的,由于引用的是指针,这4个字节怎样都会被开销掉。

8.这种情况比较少用,const修饰的引用所以不能更改a的值,但是由于a的类型是int*,并且没有被指定为const,所以:
class TestClass
{
public:
    int a;
};

void fun(TestClass* const& value)
{
    value->a = 12;
}

int main()
{
    TestClass t;
    t.a = 0;
    fun(&t);
    cout << t.a << endl;        //12  a所指向的东西被改变了
}

总结:
在使用的const的时候,要牢牢记住“右结合原则”,const会寻找右边的任何可以结合的token,类似:
int const* a;        //const在右边发现了*,所以const与*结合
const int * a;        //const向右边找,看到int,对他来说没用,因为他无法简单的与一个最简类型结合,再向右找,看到*,所以与*结合
const int a;        //同上,最终const与a结合了。
int* const& a;        //const 与&结合了
const int* const& a;    //第一个同*结合了,第二个同&结合了

int b =10;
const int* const& const a = &b;     //这个最花哨的写法了,第一个const修饰*, 第二个修饰&,第三个修饰a,由于他是引用,所以这种写法同
cosnt int* cosnt& a = &b;            //在实际上是一模一样的

看了这么多例子,应该知道结合条件了吧,const可以和*, &, 具体变量结合,但不能和int, float这种最简类型结合,当然如果你觉得和*,&这种东西结合听起来觉得不爽,那么说它和int* ,float*这种复合类型结合也是可以的。

所以,只要掌握“右结合原则”,以及“结合条件”,那么无论多么复杂的申明语句,都将难不倒你,起码,现在已经难不倒我了:)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值