C++的auto特性
由javascript引发的思考
javascript是弱类型语言,
在定义变量和函数的时候,连变量类型都不需要的,
方便得要死。
有用吗?
方便吗?
在一定程度上,程序员是不要考虑类型问题。
精力集中了、效率提高了。
C/C++能不能有这种特性?
C++的auto特性
在C++中任何被定义成为auto的变量,
它初始化的时候,
编译器就可以通过它的初始值,
推导出来变量的真正类型。
编译器来推导的。
牛B不?
编译器
为什么变量要有类型呢?
主要是为了:
让编译器知道变量需要占用多少个字节长度。
假设我们不告诉编译器变量类型。
我们给变量a一个初始值是10,
类型是auto,意思是编译器你自己猜吧。
编译器能看到10,这是一个整数。
编译器可以自己想想,这TM是什么类型?
类型可能是:
-
unsigned int
-
int
-
short
-
unsigned short
-
……
编译器懵逼了,编译器选择哪一种数据类型呢?
具体推导的时候,选择使用哪一种类型,
这个取决于写编译器的那个家伙,他怎么实现的就是怎么推导的。
函数指针的例子
// typedef一个函数指针的类型
typedef void (*func_ptr)();
//实体函数func1,用作被调用函数
void func1(){}
//参数是函数指针的func2函数
//这个函数指针,经常被用作,回调函数
void func2(func_ptr func)
{
func();
}
int main()
{
// 定义一个函数指针变量
func_ptr pfun = func1;
// 函数指针的调用
pfun();
// func2的调用
func2(pfun)
}
我们对上面的代码,使用auto进行简化一下。

对比一下,就感觉,使用auto,好TM简洁。
使用场景
在使用C++标准库的时候,
为了避免冗长的类型定义,
可以使用auto。
具体如下所示:

疑问?
既然auto能够适应任意变量,
那么模板、泛型的活,
auto是不是也能够干呢?
auto和模板、泛型对比
我们先写一个最简单的加法函数的模板,
然后做一下int类型和float类型的模板调用。
然后我们再类似地写一个auto版本,对比一下。

-
参考上图红色部分对比:auto版本中不需要模板定义的代码,模板中的T直接换成auto -
参考上图绿色部分对比:auto版本的函数调用部分,直接传递参数就可以了。
是不是auto版本更加干净、整洁呢?
auto版本和template版本,虽然语法规则通过了,但是功能上是否会一样呢?
对于功能是否一致的这个问题,我们可以对比两个版本代码的CPU指令。

可以非常明白看到,它们的CPU指令是完全相同的。
auto版本和template版本一样的。
都会偷偷生成两个函数版本。
一个用于做int类型的加法。
一个用于做float类型的加法。
感觉编译器在做代码复用。
要是这么玩,有了auto,template看上去就有点不香了。
C++的auto特性和JS对比
但是不得不说,C++的auto机制相比javascript还相对简单。
在安全性和兼容性方面,还不能够完全放手不管。
特别是在用auto代替引用类型的时候,需要特别小心。
例如,我们定义一个全局变量a,然后写一个函数get(),返回这个全局变量的引用。
然后写一个main函数调用函数get。

如果我们试图通过修改:引用变量r的值,从而把变量a的值从1修改成为2,这是不行的。
为了让auto知道,它是在代替一个引用的变量,我们必须手动地给auto加上符号:&。
这样才能够让auto正确地去代替一个引用变量,从而顺利地改变变量a的值。

总结
- 1、auto在一定程度上会简化程序代码,
增加代码的可读性。 - 2、auto在一定程度上可以
减少代码对数据类型的依赖,从而提高代码的稳定性和重构效率、扩展效率。 - 3、过度使用auto,也可能适得其反,因为auto并不能够提供足够的类型信息,当推理过程过于复杂的时候,反而会损失代码的可读性。
- 如果只是简单地用auto定义一个有初始值的变量,请放心使用auto。
- 但是如果用auto替代指针和引用类型时,就可能产生一些非预期的错误,需要谨慎使用。
弱类型和强类型,JS和TS,哪个更为合理呢?很有争议的。
弱类型有很多问题,但是易用性太强大了,所以JS太流行了。
TS和JS完全兼容,影响力不如JS。

浙公网安备 33010602011771号