auto:用来声明自动变量。它是存储类型标识符,表明变量(自动)具有本地范围,块范围的变量声明(如for循环体内的变量声明)默认为auto存储类型。
其实大多普通声明方式声明的变量都是auto变量,他们不需要明确指定auto关键字,默认就是auto的了。auto变量在离开作用域是会变程序自动释放,不会发生内存溢出情况(除了包含指针的类)。使用auto变量的优势是不需要考虑去变量是否被释放,比较安全吧。
new:new是用来在堆上申请内存地址的关键字,他产生的变量不会自动释放,除非delete来手动释放,或者程序结束时由操作系统释放,使用new的优势是内存使用比较灵活,理论可以申请任意大小的内存区块(实际与操作系统有关),但这很容易产生问题,一不小心忘记释放对象,特别是在频繁调用的函数内创建的对象忘记释放时,会产生内存溢出,严重时导致程序出错,系统崩溃。new一般都是在类的定义中使用,结合delete可以使包含new出来对象的类也具有自带变量功能,这样就继承了两种方式的优势。
--------------------------------------------------------------
另外,最新的C++标准更新了auto关键字的功能
除了具有原有的含义外,还增加了一种类似其他高级语言的型别推导特性
使用auto来代替变量的类型,
前提是被明确类型的初始化变量初始化的,可以使用auto关键字
比如int i=10; auto a = i; //这样a也是int类型了
这在使用一些模板类的时候,对于减少冗赘的代码也很有用
---------------------------------------------------------------
另外一个题外话:auto的对应类型不是使用new出来的变量,而是static变量
static变量是程序接收的时候才释放对象的,但它不需要手动释放。
static如果在一个函数内申明,这每次进入这个函数时,还是使用第一次声明的变量,并且还保存的上次使用的值(auto变量这时函数结束是即释放了,再次调用这个函数是,有重新定义了一个新的变量)
static变量如果在结构和类中使用,这结构或类定义的一切对象,都将共享唯一static变量。
一、auto
关键字的前世
从C语言开始,auto
关键字就被当作是一个变量的存储类型修饰符,表示自动变量(局部变量)。它不能被单独使用,否则编译器会给出警告。
#include <stdio.h>int main(){
int a = 123;
auto int b = 234;
auto c = 345;
printf("a = %d, b = %d, c = %d
", a, b, c);
return 0;}
编译运行结果:
$ gcc main.c
main.c:7:7: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
auto c = 345;
~~~~ ^1 warning generated.$ ./a.out
a = 123, b = 234, c = 345
二、auto
关键字的今生
在C++ 11标准中,添加了新的类型推导特性,考虑到auto
关键字很少使用,就给它重新赋予了功能——申明类型由编译器推导的变量。在C++ 11中,使用auto
定义的变量不能使用其它类型修饰符修饰,该变量的类型由编译器根据初始化数据自动确定。auto
类型的变量必须进行初始化。
#include <iostream>int main(){
int a = 21;
auto b = a;
//typeid可以获取变量或者数据类型的名字
std::cout << typeid(b).name() << std::endl;
return 0;}
1 .使用C++ 98标准进行编译,会出现警告:
$ clang++ main.cpp -std=c++98
main.cpp:6:2: warning: 'auto' type specifier is a C++11 extension
[-Wc++11-extensions]
auto b = a;
^1 warning generated.$ ./a.out
i #输出结果为整数类型
改用C++ 11进行编译:
$ clang++ main.cpp -std=c++11$ ./a.out
i
2 .但是如果还是将auto
作为存储类型修饰符使用,则在C++ 11标准下会出现警告:
#include <iostream>int main(){
int a = 21;
auto int b = a;
//typeid可以获取变量或者数据类型的名字
std::cout << typeid(b).name() << std::endl;
return 0;}
使用C++ 98编译:
$ clang++ main.cpp -std=c++98$ ./a.out
i
改用C++ 11编译,出现警告,不再允许作为存储类型修饰符使用:
$ clang++ main.cpp -std=c++11
main.cpp:6:2: warning: 'auto' storage class specifier is not permitted in C++11,
and will not be supported in future releases [-Wauto-storage-class]
auto int b;
^~~~~1 warning generated.
3 .必须要对auto
类型的变量进行初始化,C++ 98中不能单独使用auto
定义变量。
$ clang++ main.cpp -std=c++98
main.cpp:6:2: warning: 'auto' type specifier is a C++11 extension
[-Wc++11-extensions]
auto b;
^
main.cpp:6:7: error: declaration of variable 'b' with type 'auto' requires an
initializer
auto b;
^1 warning and 1 error generated.$ clang++ main.cpp
main.cpp:6:2: warning: 'auto' type specifier is a C++11 extension
[-Wc++11-extensions]
auto b;
^
main.cpp:6:7: error: declaration of variable 'b' with type 'auto' requires an
initializer
auto b;
^1 warning and 1 error generated.
三、扩展
在C++中还能使用decltype
来获取变量或者表达式的类型并用来定义新的变量。
#include <iostream>int main(){
int a = 21;
decltype(a) b;
std::cout << typeid(b).name() << std::endl;
return 0;}
编译运行结果:
$ clang++ main.cpp -std=c++98$ ./a.out
i$ clang++ main.cpp -std=c++11$ ./a.out
i