C++11新特性:关键字

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lisemi/article/details/91387501

1、auto关键字

autoC++11新增的自动变量,其原理是编译器根据上下文情况,确定组通变量的真正类型,并不是弱类型语言中的弱化变量。在真正的编程中建议尽量少使用auto,直接写出变量类型更加清晰易懂,在不知道变量类型或者冗长复杂的类型中可以考虑使用。

1.1 用于常用类型推导

int main()
{
    auto var = 10;
    auto str = "hello";
    std::cout << "var:" << var << std::endl;
    std::cout << "str:" << str << std::endl;

    std::vector<std::string> vs;
    for (auto i = vs.begin(); i != vs.end(); i++){
        //..
    }
}

 

1.2作为函数的返回值

auto add(int a, int b) 
{
    return a + b;
}

int main()
{
    auto ret = add(1,2);
    std::cout << " ret:" << ret << std::endl;
    return 0;
}

      autoC++14中可以作为函数的返回值.

既然aoto可以作为函数的返回值,那么它是否可以作为类成员函数的返回值呢?答案是只能作为类内联函数的返回值;auto作为成员函数的返回值时,只能用于函数的定义,不能用于函数的声明,即用auto作为函数返回值时,需要把函数的实现写在头文件中,这样编译器可以根据函数实现的返回值确定auto的真实类型。

1.2 在定义模块函数时使用

template <typename _Tx, typename _Ty>

void Multiply(_Tx x, _Ty y)

{

    auto v = x*y;

    std::cout << v;

}

由于不知道模块传入类型,所以刚开始都不知道x*y的类型,需要使用auto类型了推导。

1.3 模块函数依赖于模板参数的返回值

template <typename _Tx, typename _Ty>

auto multiply(_Tx x, _Ty y)->decltype(_Tx*_Ty)

{

    return x*y;

}

      当模块函数返回值依赖于模板参数时,依旧无法确定模板函数的类型,也就无法确定模板函数的类型,此时使用auto作为模板函数的返回值占位,它只是为函数的返回值占据一个位置,真正返回值是后面的decltype(_Tx*_Ty)。decltype用于查询表达式的数据类型,这里的类型(decltype(_Tx*_Ty))后置是因为如果写成正常的格式:decltype(_Tx*_Ty)multiply(_Tx x, _Ty y),这里的_Tx,_Ty还不知道是什么类型,会导致编译失败。

1.4 auto使用注意事项

1)auto变量必须在定义时初始化;

2)定义在同一个auto序列必须推导同一个种类型

auto a1 = 10, a2=10.5, a3=”hello”  // 错误

3)如果初始化表达式是引用,则会把引用语义去除

int a = 1;

int &b = a;

auto c = b;   //此时类型c没有引用语义,为int而非int&;

auto &d = b;// 相当于auto时加上引用,此时为int&

4)如果初始化表达式为const或volatile,则去除对应的特性

const int a = 1; 

auto b = a;  //const特性不会保留,可以对b进行修改

const auto c = a; // auto时加入const,不能对c进行修改

//如果auto时需要保留const或volatile特性,则可以通道应用方式进行。如下:

const int a2 = 2;

auto &b2 = a2;//加上了&,故保留了const,不能对b2修改。

5)初始化数据时,auto推导为指针;若加入&,则推导类型为数组类型。

int a = 1;

int a[3] = {1,2,3};

auto b = a;   

auto &c = a;

std::cout << typeid(b).name << std::endl;

std::cout << typeid(c).name << std::endl;

输出为:

int *

int[3]

2、nullptr

为什么需要nullptr? NULL有什么毛病?

NULLC++中就是代表着0,这是因为在C++void* 类型是不允许隐式转换成其他类型的,所以C++中用0来代表空指针,但是在重载整形的情况下,会出现上述的问题。nullptr,可以保证在任何情况下都代表空指针,而不会出现上述的情况。

例:

class Test
{
public:
    void test(int a)
    {
        std::cout << "test 1" << std::endl;
    }
    void test(int * a)
    {
        std::cout << "test 2" << std::endl;
    }
};

int main()
{
    Test test;
    test.test(NULL);
    test.test(nullptr);
}

 

  运行结果:

              test 1

              test 2

  NULLc++里表示空指针,调用test.test(NULL),其实期望是调用的是void test(int * index),但结果调用了void test(int index)。但使用nullptr的时候,能调用到正确的函数。

猜你喜欢

转载自blog.csdn.net/lisemi/article/details/91387501