C++11的好用的特性

1.C++11增加了一些关键字,其中有auto (编译时自动根据上下文类型推导),auto关键字作为函数返回类型时,不可以用于声明,只能用于函数定义。因为声明的话没办法根据上下文进行类型推导。

nullptr关键字,跟NULL的区别是什么呢?NULL既可以表示空指针也可以表示整数0,而nullptr只能表示空指针。在遇到函数重载,参数分别是int 和 int*时,使用NULL就不知道调用哪个了。

新的for循环语法,如下:

    int numbers[] = { 1,2,3,4,5 };

    std::cout << "numbers:" << std::endl;

    for (auto number : numbers)

    {

        std::cout << number << std::endl;

    }

参数更加简单方便。

2.C++11还增加了一些STL容器,使得STL更加全面了。

std::array跟数组并没有太大区别,用到多维数组反而不太方便,std::array相对于数组,增加了迭代器等函数(接口定义可参考C++官方文档)。

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

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

std::unordered_set的数据存储结构也是哈希表的方式结构,除此之外,std::unordered_set在插入时不会自动排序,这都是std::set表现不同的地方。

在C++11以前,C++的多线程编程均需依赖系统或第三方接口实现,一定程度上影响了代码的移植性。std::thread和CreateThread 的不同时,后者是平台相关的api,前者是c++本身的特性,具有可移植性。

std::atomic为C++11分装的原子数据类型。

  什么是原子数据类型?

  从功能上看,简单地说,原子数据类型不会发生数据竞争,能直接用在多线程中而不必我们用户对其进行添加互斥资源锁的类型。从实现上,大家可以理解为这些原子类型内部自己加了锁。

C++11中的std::condition_variable就像Linux下使用pthread_cond_wait和pthread_cond_signal一样,可以让线程休眠,直到别唤醒,线程再重新执行。线程等待在多线程编程中使用非常频繁,经常需要等待一些异步执行的条件的返回结果。

在内存管理方面,C++11的std::auto_ptr基础上,移植了boost库中的智能指针的部分实现,如std::shared_ptr、std::weak_ptr等,当然,boost::thread一样,C++11也修复了boost::make_shared中构造参数的限制问题。把智能指针添加为标准,个人觉得真的非常方便,毕竟在C++中,智能指针在编程设计中使用的还是非常广泛。

  什么是智能指针?网上已经有很多解释,个人觉得“智能指针”这个名词似乎起得过于“霸气”,很多初学者看到这个名词就觉得似乎很难。

  简单地说,智能指针只是用对象去管理一个资源指针,同时用一个计数器计算当前指针引用对象的个数,当管理指针的对象增加或减少时,计数器也相应加1或减1,当最后一个指针管理对象销毁时,计数器为1,此时在销毁指针管理对象的同时,也把指针管理对象所管理的指针进行delete操作。

#include <memory>

class Test

{

public:

    Test()

    {

        std::cout << "Test()" << std::endl;

    }

    ~Test()

    {

        std::cout << "~Test()" << std::endl;

    }

};

int main()

{

    std::shared_ptr<Test> p1 = std::make_shared<Test>();

    std::cout << "1 ref:" << p1.use_count() << std::endl;

    {

        std::shared_ptr<Test> p2 = p1;

        std::cout << "2 ref:" << p1.use_count() << std::endl;

    }

    std::cout << "3 ref:" << p1.use_count() << std::endl;

    return 0;

}

1、std::make_shared封装了new方法,boost::make_shared之前的原则是既然释放资源delete由智能指针负责,那么应该把new封装起来,否则会让人觉得自己调用了new,但没有调用delete,似乎与谁申请,谁释放的原则不符。C++也沿用了这一做法。

2、随着引用对象的增加std::shared_ptr<Test> p2 = p1,(有新创建的对象才是拷贝构造,否则是赋值运算符函数)指针的引用计数有1变为2,当p2退出作用域后,p1的引用计数变回1,当main函数退出后,p1离开main函数的作用域,此时p1被销毁,当p1销毁时,检测到引用计数已经为1,就会在p1的析构函数中调用delete之前std::make_shared创建的指针

std::weak_ptr网上很多人说其实是为了解决std::shared_ptr在相互引用的情况下出现的问题而存在的,C++官网对这个只能指针的解释也不多,那就先甭管那么多了,让我们暂时完全接受这个观点。

std::weak_ptr有什么特点呢?与std::shared_ptr最大的差别是在赋值是,不会引起智能指针计数增加。

3.std::function、std::bind和lamda表达式的一些特点和用法:

std::bind和std::function也是从boost中移植进来的C++新标准,这两个语法使得封装可执行对象变得简单而易用。此外,std::bind和std::function也可以结合我们一下所说的lamda表达式一起使用,使得可执行对象的写法更加“花俏”。

std::function<int(int,int)>表示std::function封装的可执行对象返回值和两个参数均为int类型。

在众多的C++11新特性中,个人觉得lamda表达式不仅仅是一个语法新特性,对于没有用过java或C#lamda表达式读者,C++11的lamda表达式在一定程度上还冲击着你对传统C++编程的思维和想法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程经验随笔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值