C++11常用新特性

1、关键字及新语法

  C++11相比C++98增加了许多关键字及新的语法特性,很多人觉得这些语法可有可无,没有新特性也可以用传统C++去实现。

  也许吧,但个人对待新技术总是抱着渴望而热衷的态度对待,也许正如很多人所想,用传统语法也可以实现,但新技术可以让你的设计更完美。这就如同在原来的维度里,你要完成一件事情,需要很多个复杂的步骤,但在新语法特性里,你可以从另外的维度,很干脆,直接就把原来很复杂的问题用很简单的方法解决了,我想着就是新的技术带来的一些编程体验上非常好的感觉。大家也不要觉得代码写得越复杂就先显得越牛B,有时候在理解的基础上,尽量选择“站在巨人的肩膀上”,可能你会站得更高,也看得更远。

  本章重点总结一些常用c++11新语法特点。后续会在本人理解的基础上,会继续在本博客内更新或增加新的小章节。

1.1、auto关键字及用法

  A、auto关键字能做什么?

  auto并没有让C++成为弱类型语言,也没有弱化变量什么,只是使用auto的时候,编译器根据上下文情况,确定auto变量的真正类型。

复制代码

//示例代码1.0 http://www.cnblogs.com/feng-sc/p/5710724.html
auto AddTest(int a, int b) 
{
    return a + b;
}

int main()
{
    auto index = 10;
    auto str = "abc";
    auto ret = AddTest(1,2);
    std::cout << "index:" << index << std::endl;
    std::cout << "str:" << str << std::endl;
    std::cout << "res:" << ret << std::endl;
}

复制代码

  是的,你没看错,代码也没错,auto在C++14中可以作为函数的返回值,因此auto AddTest(int a, int b)的定义是没问题的。

  运行结果:

    

  B、auto不能做什么?

  auto作为函数返回值时,只能用于定义函数,不能用于声明函数。

复制代码

//Test.h 示例代码1.0 http://www.cnblogs.com/feng-sc/p/5710724.html
#pragma once
class Test
{
public:
    auto TestWork(int a ,int b);
};

复制代码

  如下函数中,在引用头文件的调用TestWork函数是,编译无法通过。

  但如果把实现写在头文件中,可以编译通过,因为编译器可以根据函数实现的返回值确定auto的真实类型。如果读者用过inline类成员函数,这个应该很容易明白,此特性与inline类成员函数类似。

复制代码

//Test.h 示例代码1.0 http://www.cnblogs.com/feng-sc/p/5710724.html
#pragma once
class Test
{
public:
    auto TestWork(int a, int b)
    {
        return a + b;
    }
};

复制代码

1.2、nullptr关键字及用法

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

  我们通过下面一个小小的例子来发现NULL的一点问题:

复制代码

//示例代码1.0 http://www.cnblogs.com/feng-sc/p/5710724.html
class Test
{
public:
    void TestWork(int index)
    {
        std::cout << "TestWork 1" << std::endl;
    }
    void TestWork(int * index)
    {
        std::cout << "TestWork 2" << std::endl;
    }
};

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

复制代码

  运行结果:

     

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

1.3、for循环语法

  习惯C#或java的同事之前使用C++的时候曾吐槽C++ for循环没有想C#那样foreach的用法,是的,在C++11之前,标准C++是无法做到的。熟悉boost库读者可能知道boost里面有foreach的宏定义BOOST_FOREACH,但个人觉得看起并不是那么美观。

  OK,我们直接以简单示例看看用法吧。

复制代码

//示例代码1.0 http://www.cnblogs.com/feng-sc/p/5710724.html
int main()
{
    int numbers[] = { 1,2,3,4,5 };
    std::cout << "numbers:" << std::endl;
    for (auto number : numbers)
    {
        std::cout << number << std::endl;
    }
}

复制代码

   以上用法不仅仅局限于数据,STL容器都同样适用。

2、STL容器

  C++11在STL容器方面也有所增加,给人的感觉就是越来越完整,越来越丰富的感觉,可以让我们在不同场景下能选择跟具合适的容器,提高我们的效率。

  本章节总结C++11新增的一些容器,以及对其实现做一些简单的解释。

2.1、std::array

  个人觉得std::array跟数组并没有太大区别,对于多维数据使用std::array,个人反而有些不是很习惯吧。

  std::array相对于数组,增加了迭代器等函数(接口定义可参考C++官方文档)。

复制代码

//示例代码1.0 http://www.cnblogs.com/feng-sc/p/5710724.html
#include <array>
int main()
{
    std::array<int, 4> arrayDemo = { 1,2,3,4 };
    std::cout << "arrayDemo:" << std::endl;
    for (auto itor : arrayDemo)
    {
        std::cout << itor << std::endl;
    }
    int arrayDemoSize = sizeof(arrayDemo);
    std::cout << "arrayDemo size:" << arrayDemoSize << std::endl;
    return 0;
}

复制代码

  运行结果:

     

  打印出来的size和直接使用数组定义结果是一样的。

2.2、std::forward_list

  std::forward_list为从++新增的线性表,与list区别在于它是单向链表。我们在学习数据结构的时候都知道,链表在对数据进行插入和删除是比顺序存储的线性表有优势,因此在插入和删除操作频繁的应用场景中,使用list和forward_list比使用array、vector和deque效率要高很多。

复制代码

//示例代码1.0 http://www.cnblogs.com/feng-sc/p/5710724.html
#include <forward_list>
int main()
{
    std::forward_list<int> numbers = {1,2,3,4,5,4,4};
    std::cout << "numbers:" << std::endl;
    for (auto number : numbers)
    {
        std::cout << number << std::endl;
    }
    numbers.remove(4);
    std::cout << "numbers after remove:" << std::endl;
    for (auto number : numbers)
    {
        std::cout << number << std::endl;
    }
    return 0;
}

复制代码

猜你喜欢

转载自blog.csdn.net/Hahaha_Val/article/details/81541526
今日推荐