zoukankan      html  css  js  c++  java
  • auto与decltype

    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

     

  • 相关阅读:
    基于Visual C++2013拆解世界五百强面试题--题9-找出所有的排列方式
    基于Visual C++2013拆解世界五百强面试题--题8-数组的排序和查找
    基于Visual C++2013拆解世界五百强面试题--题7-链表的各种操作
    宣布在 Azure 镜像库中正式推出 Windows Server 2012 R2 并降低 Windows Azure 的实例定价
    基于Visual C++2013拆解世界五百强面试题--题6-double类型逆序
    基于Visual C++2013拆解世界五百强面试题--题5-自己实现strstr
    Paging
    Swapping
    Partitioning
    Stationary point
  • 原文地址:https://www.cnblogs.com/yjds/p/8597215.html
Copyright © 2011-2022 走看看