首页 > C++11新特性
头像
linux地平线
发布于 2021-07-24 15:30
+ 关注

C++11新特性

1、关键字及用法

1.1、nullptr关键字及用法auto关键字及用法

A、auto关键字能做什么?

auto并没有让C++成为弱类型语言,也没有弱化变量什么,只是使用auto的时候,编译器根据上下文情况,确定auto变量的真正类型。
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作为函数返回值时,只能用于定义函数,不能用于声明函数。
class Test{
public:
    auto TestWork(int a ,int b);
};

1.2、nullptr关键字及用法

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

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

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,我们直接以简单示例看看用法吧。
int main(){
    int numbers[] = { 1,2,3,4,5 };
    std::cout << "numbers:" << std::endl;
    for (auto number : numbers){
        std::cout << number << std::endl;
    }
}

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

更多C++11新特性关键字 C++新特性关键字

2、STL


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

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

2.1、std::array

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

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

#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效率要高很多。
#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;
}

2.3、std::unordered_map

std::unordered_map与std::map用法基本差不多,但STL在内部实现上有很大不同,std::map使用的数据结构为二叉树,而std::unordered_map内部是哈希表的实现方式,哈希map理论上查找效率为O(1)。但在存储效率上,哈希map需要增加哈希表的内存开销。

下面代码为C++官网实例源码实例:
#include <iostream>
#include <string>
#include <unordered_map>
int main(){
    std::unordered_map<std::string, std::string> mymap ={
        { "house","maison" },
        { "apple","pomme" },
        { "tree","arbre" },
        { "book","livre" },
        { "door","porte" },
        { "grapefruit","pamplemousse" }
    };
    unsigned n = mymap.bucket_count();
    std::cout << "mymap has " << n << " buckets.\n";
    for (unsigned i = 0; i<n; ++i) {
        std::cout << "bucket #" << i << " contains: ";
        for (auto it = mymap.begin(i); it != mymap.end(i); ++it)
            std::cout << "[" << it->first << ":" << it->second << "] ";
        std::cout << "\n";
    }
    return 0;
}

2.4、std::unordered_set

std::unordered_set的数据存储结构也是哈希表的方式结构,除此之外,std::unordered_set在插入时不会自动排序,这都是std::set表现不同的地方。
#include <iostream>
#include <string>
#include <unordered_set>
#include <set>
int main(){
    std::unordered_set<int> unorder_set;
    unorder_set.insert(7);
    unorder_set.insert(5);
    unorder_set.insert(3);
    unorder_set.insert(4);
    unorder_set.insert(6);
    std::cout << "unorder_set:" << std::endl;
    for (auto itor : unorder_set){
        std::cout << itor << std::endl;
    }
    std::set<int> set;
    set.insert(7);
    set.insert(5);
    set.insert(3);
    set.insert(4);
    set.insert(6);
    std::cout << "set:" << std::endl;
    for (auto itor : set){
        std::cout << itor << std::endl;
    }
}
更多C++11新特性容器 C++新特性容器















全部评论

(0) 回帖
加载中...
话题 回帖

推荐话题

相关热帖

近期精华帖

热门推荐