躁动不安的const

就是用来吓唬你的

我能想到的,最短的,且const最多的一个语句是:

int const * fun(int const*const a[],const int index)const;

而这个语句还有以下若干等价语句:

const int * fun(int const * const a[],const int index)const;
const int * fun(const int * const a[],const int index)const;
const int * fun(const int * const a[],int const index)const;
 //…

看似复杂,实际上分析const的语义时,唯一的一条原则就是:

const始终修饰其左侧的类型标识符(简单的或复合的),唯一例外是当其左侧没有类型标识符时,则修饰其右侧第一个简单类型标识符。

const与常量

好了,从最简单开始分析。使用const最简单的用法就是修饰一个简单的类型标识符。

int const varInt;

根据上面的分析原则,const修饰的是int,则表示varInt是一个整型常量,其值一旦初始化,就不可修改。

而我们知道,const的位置是很灵活的,它既可以放在类型标识符的前面,也可以放在类型标识符的后面,所以下面的写法也是正确的。

const int varInt;

这实际就是上面分析原则的例外情况,const的左侧在没有类型标识符,则其修饰其右侧的int,即表示varInt是一个整形常量。

const与指针

那么,稍微复杂些,看看指向常量的指针

const int* pInt;

这又是上面分析原则的例外情况,那么const修饰的是int(注意分析原则的描述,const修饰的是右侧第一个简单类型标识符,所以说const修饰的是int,而不是int *),表示是个整型常量,然后我们看到“* ”,表示pInt是个指针,其指向的就是个const int 常量,而pInt本质上还是个变量。

接下来理所当然得有与上面的等价的写法:

int const* pInt;

这就是分析原则里首先说的情况了,const修饰的是int,所以pInt还是一个指向整型常量的指针。如果再把const往右移一位,就发生质变了:

int * const pInt;

这时,const修饰的是int *,即整型的指针,这是一个复合类型,进一步的,const表示这个指针pInt是个常量,即一旦初始化,pInt就不能再指向别的整型变量了,这就是指针常量。当然其所指的对象还是可以被修改的。

再进一步:

const int * const pInt;
int const * const pInt;

这两个语句都是在声明一个指向整型常量的指针常量,即pInt不能被修改,其所指的对象也不能被修改。当然,在实际应用中几乎很少有这种写法。

const与成员函数

到这里,最上面的语句中,前四个const其实已经分析清楚了,就剩下最后一个了。

这个语句的本意是想声明一个函数,只是函数的参数和返回值的类型太复杂了,从而显得不值关,所以为了分析最后一个const,我们简化下这个语句:

int fun(int)const;

首先,我们区分下函数的类型和函数的名称,一般的,对于一个函数的声明:

void fun(void);

表示声明了一个名称为fun,参数为void,即无参,返回值为void,即无返回值的函数,所以这个函数的名称就是fun,类型就是参数为void,返回值为void,即void (void) .

根据上面的分析原则,const修饰的应该是int(int)。而fun是函数的名称,那么就应该理解为这是在声明一个参数为整型,返回值为整型的常量函数(听着怪怪的),实际上这种函数叫做常量成员函数,哈,一听就明白了,这表示这种函数只能做类的成员函数,而不能做全局函数。那么它的作用也就是唯一的,保证在这个函数的函数体内,不会有修改类的成员变量的操作,否则编译就会报错。

类型标识符通过const的修饰后,就变成了复合类型,也就是一种新的类型。所以使用const类修饰成员函数,也能实现成员函数的重载,即在一个类里,通过在成员函数声明的末尾带于不带const,而从形成一个成员函数的const和非const版本。当使用这种类型的const对象来调用该函数时,则调用的是该函数的const的版本,而使用非常量对象来调用该函数时,则调用的是该函数的非const版本。

如此一来,总算搞清了const,但是,我们也看到由于在const使用的灵活,在写代码时既可以放在被修饰类型标识符(只能是简单类型标识符)的前面,也可以放在被修饰类型标识符的后面,从而导致我们在读代码时会混乱,所以,建议在写代码的时候不要把const放在语句的最前面,而是仅放在被修饰的类型标识符的后面,这样在分析代码也就不用操心上述分析原则的例外情况了,这不是简单很多了嘛!

就先总结这么多了!难免有不准确之处,欢迎讨论。     :)

躁动不安的const

时间: 2024-10-01 02:25:17

躁动不安的const的相关文章

const指南

基本词义  意思就就是说利用const进行修饰的变量的值在程序的任意位置将不能再被修改,就如同常数一样使用! 使用方法 const int a=1;//这里定义了一个int类型的const常数变量a; 但对于指针来说const仍然是起作用的,以下有两点要十分注意,因为下面的两个问题很容易混淆! 我们来看一个如下的例子: //程序作者:管宁 //站点:www.cndev-lab.com //所有稿件均有版权,如要转载,请务必著名出处和作者 #include <iostream> using na

PHP 面向对象中常见关键字使用(final、static、const和instanceof)

PHP 面向对象中常见关键字的使用: 00x1.Final :final关键字可以加在类或者类中方法之前,但是不能使用final标识成员属性. 作用: 使用final标识的类,不能被继承. 在类中使用final标识的成员方法,在子类中不能覆盖. 总结:final表示为最终的意思,所以使用final关键字的类或者类中的成员方法是不能被更改的. 00x2.Static :static关键字将类中的成员属性或者成员方法标识为静态的,static标识的成员属性属于整个类,static成员总是唯一存在的,

const 放在函数后

const 放在函数后表示这个函数是常成员函数, 常成员函数是不能改变成员变量值的函数.const 限定符,它把一个对象转换成一个常量.举例:为了使成员函数的意义更加清楚,我们可在不改变对象的成员函数的函数原型中加上const说明:class Point{public:int GetX() const;int GetY() const;void SetPt (int, int);void OffsetPt (int, int);private:int xVal, yVal;};const成员函数

修改 const 的值之后的奇怪变化

1 #include <iostream> 2 3 int main(void) 4 { 5 const int a = 10; 6 int* p = (int*)&a; 7 *p = 20; 8 std::cout << a << "|" << &a << std::endl; 9 std::cout << *p << "|" << p <<

《const限定符的使用》

在程序中,对于数据,我们有一种数据希望给定了,就不会改变.书上常拿圆周率来举例! 我们把这类一开始就给定的数据,并且在程序运行过程中不改变的数据称为常量. 那么这里 也就说明了,如果要用const ,那么你要保证你那个数是个常量. 第一点:既然是不变,而我们又知道它的值,那么我们必须对他初始化.以后不能改变它! 第二点:常量在内存中有值,且伴随它所在的作用域存在,可以理解为大括号内. 第三点:const修饰什么,什么就是常量(下边将结合一些代码,给出几种常量类型) #include "stdaf

const总结

const const限定符将一个对象转换成一个常量,限定了其值不允许改变. 常变量 int const val=5;//两种方法都可以: const int val1=6;//因为常量在定义后不能改变,所以定义时必须初始化: 任何企图修改val和val1的操作都会引起编译错误: const引用 const应用是指向const对象的引用 不能将普通的引用绑定到const对象: const int r=10; const int &r1=r;//不能对r1赋值: int &r2=r;//错误

const的使用总结(转载)

C++中的const关键字的用法非常灵活,而使用const将大大改善程序的健壮性,本人根据各方面查到的资料进行总结如下,期望对朋友们有所帮助. Const 是C++中常用的类型修饰符,常类型是指使用类型修饰符const说明的类型,常类型的变量或对象的值是不能被更新的. 一.Const作用    如下表所示: No. 作用 说明 参考代码 1 可以定义const常量 const int Max = 100; 2 便于进行类型检查 const常量有数据类型,而宏常量没有数据类型.编译器可以对前者进行

请问微信小程序let和var以及const有什么区别

在JavaScript中有三种声明变量的方式:var.let.const. var:声明全局变量,换句话理解就是,声明在for循环中的变量,跳出for循环同样可以使用. [JavaScript] 纯文本查看 复制代码 ? 1 2 3 4 5 for(var i=0;i<=1000;i++){ var sum=0; sum+=i; } alert(sum); 声明在for循环内部的sum,跳出for循环一样可以使用,不会报错正常弹出结果 let:声明块级变量,即局部变量. 在上面的例子中,跳出fo

概览C++之const

1.C语言中const与 C++中的const void main() { const int a = 10; int *p = (int*)&a; *p = 20; printf("%d", a); } 比較上述代码在C中和C++中执行结果:C:打印20:C++:打印0. 由此可见,C语言中的const是个"冒牌货",C++中 的const是一个真正的常量. 原因:C语言直接为a分配了内存. C语言中的const变量是仅仅读变量,有自己的存储空间.而C++