const限定符和auto类型说明符

const限定符

1.限定常量

有时我们希望定义这样的变量:它的值不能被改变。为了满足这一要求,我们使用const对变量的类型加以限定:

const int bufSize = 512;

这样就把bufSize定义成了一个常量,它的值不能再发生变化。所以这也就意味着const对象必须要初始化。
那么初始化操作对于const对象来说意味着什么呢?
如果利用一个对象去初始化另外一个对象,则它们是不是const都无关紧要:

int i = 42;
const int ci = i;  //正确
int j = ci;  //正确

这里要注意的是,虽然使用常量ci去初始化j,但是拷贝一个对象的值并不会改变它,一旦完成拷贝,新的对象就和原来的对象没有什么关系了。

2.const对象仅在文件内有效

默认情况下,const对象被限定仅在文件内有效。当多个文件中出现了同名的const变量时,其实等同于在不同文件中分别定义了独立的变量。
但是,如果需要将const变量在多个文件中实现共享该怎么办呢?
要做到在一个文件中定义const,而在其它多个文件中声明并且使用它,解决的办法就是:对于const变量不管是声明还是定义都添加extern关键字,这样只需要定义一次就够了。

//第一个文件file1
extern const int bufSize = fcn();
//第二个文件file2
extern const int bufSize;  //与file1里面的是同一个

const的引用

对常量的引用不能被用作修改它所绑定的对象:

const int ci = 1024;
const int &r1 = ci;  //正确,引用及其对应的对象都是常量
r1 = 42;    //错误,r1是对常量的引用
int &r2 = ci;    //错误,r2是非常量引用,ci是一个常量

我们知道,引用的类型必须与其所引用的对象的类型一致,但是有两个特殊情况:
(1)初始化常量引用时允许用任意表达式作为初始值,只要该表达式的结果能转换成引用的类型即可。

double dval = 3.14;
const int &ri = dval;

ri引用了一个int型的数,但是dval确实一个双精度浮点数,编译器会将其变成如下形式:

const int temp = dval;
const int &ri = temp;

(2)对const的引用可能引用一个并非const的对象

int i = 42;
const int &ri = i;

这种方式是允许的。

const与指针

顶层const

顶层const表示指针本身是一个常量,不能改变它的指向。

int i = 43;
int * const p1 = &i;
底层const表示指针所指的对象是一个常量。
int i = 43;
const int * p1 = &i;
int const * p2 = &i;

常量表达式与constexpr

常量表达式指的是值不会改变且在编译过程中就能得到计算结果的表达式

const int max_file = 20;    //是常量表达式
const int limit = max_file + 1    //limit是常量表达式
int stuff_size = 10;      //stuff_size不是常量表达式
const int sz = getSize();     //sz不是常量表达式

C++11标准规定,允许将变量声明为constexpr类型以便由编译器来验证变量的值是否是一个常量表达式。声明为constexpr的变量一定是一个常量,而且必须用常量表达式初始化:

constexpr int mf = 20;  //  正确
constexpr int limit = mf + 1;    //mf+1是常量表达式
constexpr int sz = size();      //只有当size()是一个constexpr函数时才是一条正确的语句

需要注意的是,在constexpr声明中如果定义了一个指针,限定符constexpr仅针对指针有效,与所指的对象无关。

auto类型说明符

C++11引入auto类型说明符,它可以让编译器通过初始值来推断变量的类型。显然,auto定义的变量必须有初始值。
但是,auto会忽略掉顶层const,:

const int ci = i, &cr = ci;
auto b = ci;     //b是一个整数
auto c = cr;    //c是一个整数
auto d = &i; //d是一个整型指针
auto e = &ci;  //e是一个指向整型常量的指针(这是底层const)

但是,有时会遇到一种情况:我想知道这个表达式结果的类型,但是我又不想真的用这个表达式的结果来初始化变量。这个时候就要用到另外一个类型指示符decltype

decltype(f()) sum = x;    //sum的类型就是f()函数的返回类型

编译器并不会实际调用函数f(),而是使用当调用发生时f的返回值类型作为sum的类型。
decltype的一个坑:
对于decltype所用的表达式来说,如果decltype给变量加上括号,则返回的是引用类型:

int i = 42;
decltype((i)) d;    //错误,d是int&,必须初始化
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容