C++11特性,部分理解记录

149 阅读4分钟
  • 右值引用与move

    • 右值引用

      zhuanlan.zhihu.com/p/64265357

      zhuanlan.zhihu.com/p/335994370

      左值右值:左值可以取地址、位于等号左边;而右值没法取地址,位于等号右边。

      再看下右值引用,右值引用的标志是&&,顾名思义,右值引用专门为右值而生,可以指向右值,不能指向左值。被声明出来的左、右值引用都是左值。 因为被声明出的左右值引用是有地址的,也位于等号左边。

      1.从性能上讲,左右值引用没有区别,传参使用左右值引用都可以避免拷贝。

      2.右值引用可以直接指向右值,也可以通过std::move指向左值;而左值引用只能指向左值(const左值引用也能指向右值)。

      3.作为函数形参时,右值引用更灵活。虽然const左值引用也可以做到左右值都接受,但它无法修改,有一定局限性。

    • std::move应用场景

      1  实现移动语义。在实际场景中,右值引用和std::move被广泛用于在STL和自定义类中实现移动语义,避免拷贝,从而提升程序性能。 在没有右值引用之前,一个简单的数组类通常实现如下,有构造函数、拷贝构造函数、赋值运算符重载、析构函数等。深拷贝/浅拷贝在此不做讲解。

      2  vector::push_back使用std::move提高性能,std::move本身只做类型转换,对性能无影响。 我们可以在自己的类中实现移动语义,避免深拷贝,充分利用右值引用和std::move的语言特性。

  • 智能指针

    blog.csdn.net/flowing_win…

    zhuanlan.zhihu.com/p/54078587?…

    blog.csdn.net/zhourong051…

    • shared_ptr

      shared_ptr p(ptr):传入ptr指针作为shared_ptr的指向

      shared_ptr p(unique_ptr):传入unique_ptr作为shared_ptr的指向

      shared_ptr p(ptr,de):传入ptr作为shared_ptr的指向,并用de取代delete进行释放

      shared_ptr p(p2,de):传入shared_ptr的拷贝,并利用de取代delete进行释放

      p.reset():将shared_ptr置空

      p.reset(ptr):将shared_ptr指针指向传递入内的ptr中

      p.reset(ptr,de):将shared_ptr指针指向传递入内的ptr中,并用de取代delete进行释放

      • 可能出现的陷阱

        (1)不使用相同的内置指针值初始化(或reset)多个智能指针。

        (2)不delete get()返回的指针。

        (3)不使用get()初始化或reset另一个智能指针。

        (4)如果使用get()返回的指针,当最后一个对应的智能指针销毁后,指针就变为无效。

        (5)如果使用智能指针管理的资源不是new分配的内存,记住传递给它一个删除器。

      • 应注意的问题

        (1)专门用于共享所有权,内部使用引用计数use_count() ,因此可以支持复制、参数传递等,也是用于管理单个堆内存对象的。

        (2)同样没有release() 函数。

    • auto_ptr

      auto_ptr事实上是一个类,在构造对象时获取对象的管理权, 无需考虑释放动态内存开辟的空间,在析构函数中直接释放,不会出现内存泄漏的问题。

      • 可能出现的缺陷

        1.一个指针变量指向的空间不能由两个auto_ptr管理,不然会析构两次,使程序崩溃。

        2.auto_ptr的拷贝构造,将源指针的管理权交给目标指针,会使得源指针悬空,解引用是会出现很多问题。

        3.auto_ptr不能用来管理数组,析构函数中用的是delete

      • 应注意的问题

        (1)    尽量不要使用“operator=”。如果使用了,请不要再使用先前对象。

        (2)    记住 release() 函数不会释放对象,仅仅归还所有权。

        (3)    std::auto_ptr 最好不要当成参数传递(读者可以自行写代码确定为什么不能)。

        (4)    由于 std::auto_ptr 的“operator=”问题,有其管理的对象不能放入 std::vector 等容器中。

    • scoped_ptr

      • scoped_ptr防拷贝:

        1.拷贝构造函数和赋值运算符重载函数只声明不实现

        2.用private对其进行访问限定,防止在类外定义

      • 缺陷

        不能进行拷贝构造,管理的对象不能共享所有权,功能不全面。

      • 应注意的问题

        (1)scoped_ptr 没有 release 函数

        (2)没有重载 operator=,不会导致所有权转移,但无法赋值,拷贝智能指针。

        (3)scoped_ptr 没有重载 operator*

        (4)没有重载 operator=

    • scoped_array

      scoped_array 和 scoped_ptr的功能是一样的,只是scoped_array管理的对象是数组,需要重载[]的形式。

      • 应注意的问题

        (1)用于管理动态数组

        (2) boost::scoped_array my_memory(new Simple[2]); // 使用内存数组来初始化

    • unique_ptr

      unique_ptr p2(p1.release());//release将p1置为空

      unique_ptrp3(new string("text"));//将所有权从p3转移到p2

      p2.reset(p3.release());//reset释放了p2原来指向的内存

    • weak_ptr

      weak_ptr w:设置一个空的weak_ptr

      weak_ptr w(ptr):将weak_ptr赋值指向与ptr指向相同的对象

      w=p;w与p共享对象,其中p可以为shared_ptr或者另一个weak_ptr

      w.reset():将w置空

      w.use_count():与w共享对象的shared_ptr的数量

      w.expired():若w.use_count==0,则返回true,反之返回false

      w.lock():若expired==true,则返回一个空的shared_ptr,反之返回一个指向w的对象的shared_ptr

      • 注意:

        由于对象可能不存在,我们不能使用weak_ptr直接访问对象,而必须调用lock,此函数检查weak_ptr指向的对象是否存在。如果存在,lock返回一个指向共享对象的shared_ptr,如果不存在,lock将返回一个空指针