C++11中的智能指针unique_ptr、shared_ptr和weak_ptr详解

这篇具有很好参考价值的文章主要介绍了C++11中的智能指针unique_ptr、shared_ptr和weak_ptr详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1、引言

2、什么是智能指针?

3、在Visual Studio中查看智能指针的源码实现

4、独占式指针unique_ptr

4.1、查看unique_ptr的源码实现片段

4.2、为什么unique_ptr的拷贝构造函数和复制函数被delete了?(面试题)

4.3、使用unique_ptr独占式智能指针的实例

5、共享式指针shared_ptr 

5.1、查看shared_ptr的源码实现片段

5.2、shared_ptr的类图说明

5.3、shared_ptr循环引用问题(面试题)

5.4、使用shared_ptr的实例

6、弱指针weak_ptr

6.1、查看weak_ptr的源码实现片段

6.2、使用weak_ptr的实例

7、使用智能指针是否会影响到程序的执行效率?

8、有必要学习C++11标准中的新特性

9、最后


VC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)https://blog.csdn.net/chenlycly/article/details/124272585C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)https://blog.csdn.net/chenlycly/article/details/125529931C++软件分析工具案例集锦(正在更新中...)https://blog.csdn.net/chenlycly/category_12279968.htmlC/C++基础与进阶(正在更新中...)https://blog.csdn.net/chenlycly/category_11931267.html       C++11引入了unique_ptr、shared_ptr和weak_ptr三个智能指针,给我们编写C++代码带来了很大的便利,今天我们就来详细讲讲这三个智能指针的相关内容。

1、引言

       在C++程序中,大部分异常问题都是与内存相关的,都是内存操作异常引起的。对于动态申请的堆内存,C++没有内存回收机制,动态申请的内存需要程序员自己去释放。如果不去释放,则会造成内存泄漏。内存泄漏是个很常见的问题,在日常开发过程中会时不时地遇到。发生内存泄漏的代码如果频繁执行,则会导致持续的内存泄漏,长时间运行之后就会使得程序占用的虚拟内存接近或超过进程的虚拟内存上限,就会导致Out of memory内存耗尽的异常,引发程序发生闪退或崩溃。

以32位程序为例,程序启动时系统会给程序进程分配4GB的虚拟内存空间,其中内核态和用户态内存各占一半,即用户态内存为2GB,如果用户态的代码占用的用户态虚拟内存达到或超过2GB,就会触发Out of memory内存耗尽的异常。

       C++11标准引入三个智能指针:unique_ptr、shared_ptr和weak_ptr,使用这些智能指针就能很好地解决内存泄漏的问题。


       在这里,给大家重点推荐一下我的两个热门畅销专栏

专栏1(该专栏订阅量接近350个,有很强的实战参考价值,广受好评!)

C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)https://blog.csdn.net/chenlycly/article/details/125529931

本专栏根据近几年C++软件异常排查的项目实践,系统地总结了引发C++软件异常的常见原因以及排查C++软件异常的常用思路与方法,详细讲述了C++软件的调试方法与手段,以图文并茂的方式给出具体的实战问题分析实例,带领大家逐步掌握C++软件调试与异常排查的相关技术,适合基础进阶和想做技术提升的相关C++开发人员!

专栏中的文章都是通过项目实战总结出来的,有很强的实战参考价值!专栏文章还在持续更新中,预计文章篇数能更新到200篇以上!

专栏2: 

C/C++基础与进阶(专栏文章,持续更新中...)https://blog.csdn.net/chenlycly/category_11931267.html

以多年的开发实战为基础,总结并讲解一些的C/C++基础与进阶内容,以图文并茂的方式对相关知识点进行详细地展开与阐述!专栏涉及了C/C++领域的多个方面的内容,同时给出C/C++及网络方面的常见笔试面试题,并详细讲述Visual Studio常用调试手段与技巧!


2、什么是智能指针?

       其实早在1998年发布的C++98标准中就引入了智能指针auto_ptr,不过auto_ptr有一些缺陷,现在已经被废弃了。

       C++智能指针是存储指向动态分配(堆)对象指针的类,用于C++类对象的生存期的控制,确保在离开指针所在作用域时,自动地销毁动态分配的对象,防止内存泄露。智能指针的核心实现技术是引用计数,每引用C++对象1次,内部引用计数就加1;智能指针每析构1次,内部的引用计数就减1,当引用计数减为0时,就会删除指向的C++类对象(释放类对象的堆内存)。

C++11中的智能指针unique_ptr、shared_ptr和weak_ptr详解

        C++11标准引入三个智能指针unique_ptr、shared_ptr和weak_ptr,位于C++标准STL库中,在 <memory> 头文件中的 std 命名空间中定义的。

这个地方需要注意一下,有的朋友可能会以为STL只包含vector、list和map等容器,其实大家平常使用的字符串类string、输入输出iostream、unique_ptr等智能指针,都是STL标准模板库中的。STL模板库不仅仅包含容器和迭代器。C++标准库主要由C库、C++库和STL标准模板库构成,其中STL标准模板库在C++标准库中比重占了80%左右,即C++标准库中一大半都是STL库。

       C++11标准中主要使用unique_ptr和shared_ptr两智能指针,weak_ptr则主要用来辅助shared_ptr,避免出现循环引用问题的。在使用unique_ptr和shared_ptr两个智能指针类时,可以使用指针运算符(-> 和 *)访问指向的对象,因为智能指针类重载了->和*运算符,以返回指向的对象(指针)。

_NODISCARD add_lvalue_reference_t<_Ty> operator*() const
    {    // return reference to object
        return (*get());
    }

_NODISCARD pointer operator->() const noexcept
    {    // return pointer to class object
        return (this->_Myptr());
    }

_NODISCARD pointer get() const noexcept
    {    // return pointer to object
        return (this->_Myptr());
    }

3、在Visual Studio中查看智能指针的源码实现

        C++11引入的unique_ptr、shared_ptr和weak_ptr,可以直接在Visual Studio中查看源码实现。这三个智能指针位于STL库中,而Visual Studio采用的是P.J. STL版本。

C++11中的智能指针unique_ptr、shared_ptr和weak_ptr详解

       注意一下,要在Visual Studio中查看unique_ptr和shared_ptr实现源码,需要使用Visual Studio 2015或以上版本,低版本的Visual Studio可能不支持C++11标准或者支持了部分C++11新特性。比如Visual Studio 2010中只支持了部分C++11的新特性,比如匿名函数(lamda表达式),但不支持unique_ptr和shared_ptr智能指针(会显示未定义)。

       目前,STL主要有5个版本:

C++11中的智能指针unique_ptr、shared_ptr和weak_ptr详解

1)HP 原始版本
       HP STL 是 Alexandar Stepanov(STL 标准模板库之父)在惠普 Palo Alto 实验室工作时,与 Meng Lee 合作完成的。本着开源精神,他们声明允许任何人任意运用、拷贝、修改、传播、商业使用这些代码,无需付费。唯一要遵守的是,必修在文件中加上HP的版本声明和运用权限声明。 
2)P. J. 实现版本
       由 P. J. Plauger 开发,继承自 HP 版本,该版本不开源,不能公开、修改或贩卖。该版本不开源也是合法的,因为HP没要求强迫要求其衍生产品必须开源。该版本被微软 Visual C++ 采用,缺陷是,可读性比较低,符号命名也比较怪异。但我们在Visual Studio中阅读该版本的实现源码时,感觉还好,也没传说中那么难读。
3)RW 实现版本
       由 Rouge Wage 公司开发,继承自 HP 版本,被Borland公司的 C+ + Builder 采用。该版本也不是开源的,不能公开、修改或贩卖,这个版本的可读性还不错。
由 Rouge Wage 公司开发,继承自 HP 版本,被Borland公司的 C+ + Builder 采用。该版本也不是开源的,不能公开、修改或贩卖,这个版本的可读性还不错。值得一提的是,尽管 Rouge Wave STL 的性能不是很好,但 C++ Builder 对 C++ 语言标准的支持还算不错,所以在一定程度上使 Rouge Wave STL 的表现得以改善。但遗憾的是,由于 Rouge Wave STL 长期没有更新且不完全符合标准,因此 Rouge Wave STL 在 6.0 版本时改用了 STLport 版本(之后的版本也都采用了 STLport),不过考虑到和之前版本的兼容,6.0 版本中依旧保留了 Rouge Wave STL。
4)SGI 实现版本
        由 Silicon Graphics Computer Systems,Inc 公司开发,继承自 HP 版本。该版本被 Linux GCC 采用,可移植性好, 在 Linux 平台上的性能非常出色。该版本是开源的,可公开、修改甚至贩卖。 无论是符号命名,还是编程风格,这个版本的可读性非常高。如果大家要学习 STL源码,推荐大家看这个版本的源码实现。侯捷老师的经典书籍《STL源码剖析》,也是基于这个版本展开的。
5)STLport 实现版本
        为了使 SGI STL 的基本代码都适用于 VC++ 和 C++ Builder 等多种编译器,俄国人 Boris Fomitchev 建立了一个 free 项目来开发 STLport,此版本 STL 是开放源码的。由于 Rouge Wave STL 长期没有更新且不完全符合标准,因此 Rouge Wave STL 在 6.0 版本时改用了 STLport 版本,之后的版本也都采用了 STLport。

4、独占式指针unique_ptr

        unique_ptr是独占式智能指针,它拥有对其所指向对象的唯一所有权。unique_ptr 指针被销毁时,它所指向的对象也会被销毁。由于其具有独占性,所以unique_ptr 不能被拷贝,只能被转移所有权。将对象的所有权转移到新的unique_ptr对象中,原先的unique_ptr对象不再指向原来的对象。

4.1、查看unique_ptr的源码实现片段

        可以在Visual Studio中输入unique_ptr,然后go到unique_ptr的定义处查看unique_ptr的源码实现,都是基于模板实现的:(下面给出部分unique_ptr的源码)

    // CLASS TEMPLATE unique_ptr SCALAR
template<class _Ty,
    class _Dx>    // = default_delete<_Ty>
    class unique_ptr
        : public _Unique_ptr_base<_Ty, _Dx>
    {    // non-copyable pointer to an object
public:
    typedef _Unique_ptr_base<_Ty, _Dx> _Mybase;
    typedef typename _Mybase::pointer pointer;
    typedef _Ty element_type;
    typedef _Dx deleter_type;

    using _Mybase::get_deleter;

    template<class _Dx2 = _Dx,
        _Unique_ptr_enable_default_t<_Dx2> = 0>
        constexpr unique_ptr() noexcept
            : _Mybase(pointer())
        {    // default construct
        }

    template<class _Dx2 = _Dx,
        _Unique_ptr_enable_default_t<_Dx2> = 0>
        constexpr unique_ptr(nullptr_t) noexcept
            : _Mybase(pointer())
        {    // null pointer construct
        }

    unique_ptr& operator=(nullptr_t) noexcept
        {    // assign a null pointer
        reset();
        return (*this);
        }

    template<class _Dx2 = _Dx,
        _Unique_ptr_enable_default_t<_Dx2> = 0>
        explicit unique_ptr(pointer _Ptr) noexcept
            : _Mybase(_Ptr)
        {    // construct with pointer
        }
        
        // ...(余下源码省略)
    }

源码就不在此解读了,感兴趣可以去详细看看。源码中到处都是模板,需要有一定的模板编程基础才能看懂。

4.2、为什么unique_ptr的拷贝构造函数和复制函数被delete了?(面试题)

       现在C++岗位面试时,很多公司都喜欢问C++11新标准中的若干特性,所以大家在面试前需要详细看看C++11新特性。

       之前有个同事出去面试时,就被问到为什么unique_ptr的拷贝构造函数和复制函数被delete了?在unique_ptr的实现代码中可以看到:

unique_ptr(const unique_ptr&) = delete;
unique_ptr& operator=(const unique_ptr&) = delete;

其实很简单,因为unique_ptr是独占式的,不能进行拷贝,只能进行对象所有权的转移。拷贝构造函数与赋值函数进行的是拷贝操作,所以要将这两个函数禁用掉。

注意此处在函数后面添加“= delete”,是C++11新标准中新增的,是用来禁用对应的函数的。

4.3、使用unique_ptr独占式智能指针的实例

        使用unique_ptr智能指针的简单示例如下: 

#include <iostream>
#include <memory>

class LargeObject
{
public:
    void DoSomething(){}
};

void SmartPointerDemo()
{
    // Create the object and pass it to a smart pointer
    std::unique_ptr<LargeObject> pLarge(new LargeObject());

    //Call a method on the object
    pLarge->DoSomething();

    // Free the memory before we exit function block.
    pLarge.reset();

    // Do some other work...
}

5、共享式指针shared_ptr 

        shared_ptr是共享式智能指针,一个对象可以被多个shared_ptr共享。每个shared_ptr内部都维护一个引用计数,当引用计数为 0 时,所指向的对象会被销毁。std::shared_ptr 可以被拷贝和移动。

5.1、查看shared_ptr的源码实现片段

       可以在Visual Studio中输入shared_ptr,然后go到shared_ptr的定义处查看shared_ptr的源码实现,都是基于模板实现的:(下面给出部分shared_ptr的源码)

    // CLASS TEMPLATE shared_ptr
template<class _Ty>
    class shared_ptr
        : public _Ptr_base<_Ty>
    {    // class for reference counted resource management
private:
    using _Mybase = _Ptr_base<_Ty>;

public:
    using typename _Mybase::element_type;

#if _HAS_CXX17
    using weak_type = weak_ptr<_Ty>;
#endif /* _HAS_CXX17 */

    constexpr shared_ptr() noexcept
        {    // construct empty shared_ptr
        }

    constexpr shared_ptr(nullptr_t) noexcept
        {    // construct empty shared_ptr
        }

    template<class _Ux,
        enable_if_t<conjunction_v<conditional_t<is_array_v<_Ty>, _Can_array_delete<_Ux>, _Can_scalar_delete<_Ux>>,
            _SP_convertible<_Ux, _Ty>>, int> = 0>
        explicit shared_ptr(_Ux * _Px)
        {    // construct shared_ptr object that owns _Px
        _Setp(_Px, is_array<_Ty>{});
        }

    template<class _Ux,
        class _Dx,
        enable_if_t<conjunction_v<is_move_constructible<_Dx>,
            _Can_call_function_object<_Dx&, _Ux *&>,
            _SP_convertible<_Ux, _Ty>>, int> = 0>
        shared_ptr(_Ux * _Px, _Dx _Dt)
        {    // construct with _Px, deleter
        _Setpd(_Px, _STD move(_Dt));
        }

    template<class _Ux,
        class _Dx,
        class _Alloc,
        enable_if_t<conjunction_v<is_move_constructible<_Dx>,
            _Can_call_function_object<_Dx&, _Ux *&>,
            _SP_convertible<_Ux, _Ty>>, int> = 0>
        shared_ptr(_Ux * _Px, _Dx _Dt, _Alloc _Ax)
        {    // construct with _Px, deleter, allocator
        _Setpda(_Px, _STD move(_Dt), _Ax);
        }

    template<class _Dx,
        enable_if_t<conjunction_v<is_move_constructible<_Dx>,
            _Can_call_function_object<_Dx&, nullptr_t&>
        >, int> = 0>
        shared_ptr(nullptr_t, _Dx _Dt)
        {    // construct with nullptr, deleter
        _Setpd(nullptr, _STD move(_Dt));
        }

    template<class _Dx,
        class _Alloc,
        enable_if_t<conjunction_v<is_move_constructible<_Dx>,
            _Can_call_function_object<_Dx&, nullptr_t&>
        >, int> = 0>
        shared_ptr(nullptr_t, _Dx _Dt, _Alloc _Ax)
        {    // construct with nullptr, deleter, allocator
        _Setpda(nullptr, _STD move(_Dt), _Ax);
        }

    template<class _Ty2>
        shared_ptr(const shared_ptr<_Ty2>& _Right, element_type * _Px) noexcept
        {    // construct shared_ptr object that aliases _Right
        this->_Alias_construct_from(_Right, _Px);
        }

    shared_ptr(const shared_ptr& _Other) noexcept
        {    // construct shared_ptr object that owns same resource as _Other
        this->_Copy_construct_from(_Other);
        }
        
        // ...(余下源码省略)
}

5.2、shared_ptr的类图说明

       shared_ptr类内部实现类图如下:

C++11中的智能指针unique_ptr、shared_ptr和weak_ptr详解

shared_ptr类继承于_Ptr_base类,_Ptr_base类内部包含了指向外部对象的成员_Ptr和_Ref_count_base计数对象。根据外部调用shared_ptr的哪个构造函数,确定到底是new出_Ref_count_obj、_Ref_count或者_Ref_count_resource中哪个计数对象。类图很重要,类图可以表明各个相关类的关系,无论是写设计文档,还是学习源码,都需要使用到类图。

5.3、shared_ptr循环引用问题(面试题)

       使用shared_ptr可能会出现循环引用问题,场景是两个类中都包含了指向对方的shared_ptr对象,这样会导致new出来的两个类没有走析构,引发内存泄漏问题。

       循环引用问题的示意图如下:

C++11中的智能指针unique_ptr、shared_ptr和weak_ptr详解

相关代码如下:

#include <iostream>
#include<memory>
 
using namespace std;
 
class B;
class A{
public:
    shared_ptr<B> bptr;
    ~A(){cout<<"~A()"<<endl;}
}
 
class B
{
public:
    shared_ptr<A> aptr;
    ~B( ){cout<<"~B()"<<endl;}
}

int main() {
    shared_ptr<A> pa(new A()); // 引用加1
    shared_ptr<B> pb(new B()); // 引用加1
    pa->bptr = pb; // 引用加1
    pa->aptr = pa; // 引用加1
    return 0;
}

       执行到上述return 0这句代码时,指向A和B两个对象的引用计数都是2。当退出main函数时,先析构shared_ptr<B> pb对象,B对象的引用计数减1,B对象的引用计数还为1,所以不会delete B对象,不会进入B对象析构函数,所以B类中的shared_ptr<A> aptr成员不会析构,所以此时A对象的引用计数还是2。当析构shared_ptr<A> pa时,A的引用计数减1,A对象的引用计数变为1,所以不会析构A对象。所以上述代码会导致A和B两个new出的对象都没释放,导致内存泄漏。

       为了解决上述问题,引入了weak_ptr,可以将类中包含的shared_ptr成员换成weak_ptr,如下:

C++11中的智能指针unique_ptr、shared_ptr和weak_ptr详解

相关代码如下:

#include <iostream>
#include<nemory>
 
using namespace std;
 
class B;
class A{
public:
    weak_ptr<B> bptr;  // 使用weak_ptr替代shared_ptr
    ~A(){cout<<"~A()"<<endl;}
}
 
class B
{
public:
    weak_ptr<A> aptr; // 使用weak_ptr替代shared_ptr
    ~B( ){cout<<"~B()"<<endl;}
}

int main() {
    shared_ptr<A> pa(new A());
    shared_ptr<B> pb(new B());
    pa->bptr = pb;
    pa->aptr = pa;
    return 0;
}

5.4、使用shared_ptr的实例

        使用shared_ptr的实例代码如下:

#include <iostream>
#include <memory>
 
int main() 
{ 
    std::shared_ptr<int> sharedPtr1 = std::make_shared<int>(10);
    std::shared_ptr<int> sharedPtr2 = sharedPtr1;
    std::cout << *sharedPtr1 << std::endl; // 输出 10
    std::cout << *sharedPtr2 << std::endl; // 输出 10
 
    // 使用智能指针自动管理内存,不需要手动释放
    // 智能指针会自动更新引用计数
    sharedPtr1.reset();
 
    // 只有当所有引用都被释放后,内存才会被自动释放
    std::cout << "sharedPtr2 use count: " << sharedPtr2.use_count() << std::endl; // 输出 1
}

6、弱指针weak_ptr

        weak_ptr是为了配合shared_ptr而引入的一种智能指针,它不具有普通指针的行为,没有重载*和->两个操作符,它的最大作用在于协助shared_ptr工作,像旁观者那样观测资源的使用情况。

        weak_ptr可以从一个shared_ptr或者另一个weak_ptr对象构造,获得资源的观测权。但weak_ptr没有共享资源,它的构造不会引起指针引用计数的增加。使用weak_ptr的成员函数use_count()可以观测资源的引用计数,另一个成员函数expired()的功能等价于use_count()==0,但更快,表示被观测的资源 (也就是shared_ptr的管理的资源)已经不复存在。weak_ptr可以使用一个非常重要的成员函数lock()从被观测的shared_ptr 获得一个可用的shared_ptr对象,从而操作资源。但当expired()==true的时候,lock()函数将返回一个存储空指针的shared_ptr。

6.1、查看weak_ptr的源码实现片段

       到Visual Studio中可以看到weak_ptr的源码实现:

// CLASS TEMPLATE weak_ptr
template<class _Ty>
    class weak_ptr
        : public _Ptr_base<_Ty>
    {    // class for pointer to reference counted resource
public:
    constexpr weak_ptr() noexcept
        {    // construct empty weak_ptr object
        }

    weak_ptr(const weak_ptr& _Other) noexcept
        {    // construct weak_ptr object for resource pointed to by _Other
        this->_Weakly_construct_from(_Other);
        }

    template<class _Ty2,
        enable_if_t<_SP_pointer_compatible<_Ty2, _Ty>::value, int> = 0>
        weak_ptr(const shared_ptr<_Ty2>& _Other) noexcept
        {    // construct weak_ptr object for resource owned by _Other
        this->_Weakly_construct_from(_Other);
        }

    template<class _Ty2,
        enable_if_t<_SP_pointer_compatible<_Ty2, _Ty>::value, int> = 0>
        weak_ptr(const weak_ptr<_Ty2>& _Other) noexcept
        {    // construct weak_ptr object for resource pointed to by _Other
        this->_Weakly_construct_from(_Other.lock());
        }

    weak_ptr(weak_ptr&& _Other) noexcept
        {    // move construct from _Other
        this->_Move_construct_from(_STD move(_Other));
        }

    template<class _Ty2,
        enable_if_t<_SP_pointer_compatible<_Ty2, _Ty>::value, int> = 0>
        weak_ptr(weak_ptr<_Ty2>&& _Other) noexcept
        {    // move construct from _Other
        this->_Weakly_construct_from(_Other.lock());
        _Other.reset();
        }

    ~weak_ptr() noexcept
        {    // release resource
        this->_Decwref();
        }

    weak_ptr& operator=(const weak_ptr& _Right) noexcept
        {    // assign from _Right
        weak_ptr(_Right).swap(*this);
        return (*this);
        }

    template<class _Ty2>
        weak_ptr& operator=(const weak_ptr<_Ty2>& _Right) noexcept
        {    // assign from _Right
        weak_ptr(_Right).swap(*this);
        return (*this);
        }
        
        // ...(余下源码省略)
}

6.2、使用weak_ptr的实例

#include <iostream>  
using namespace std;  
#include <memory>  
  
class B;  
  
class A  
{  
public:  
    weak_ptr<B> ptrA_B;  // 弱类型指针

public:  
    A()  
    {  
        cout << "调用class A的构造函数" << endl;  
    }  
    ~A()  
    {  
        cout << "调用class A的析构函数" << endl;  
    }  
};  
  
class B  
{  
public:  
    weak_ptr<A> ptrB_A;  // 弱类型指针

public:  
    B()  
    {  
        cout << "调用class B的构造函数" << endl;  
    }  
    ~B()  
    {  
        cout << "调用class B的析构函数" << endl;  
    }  
};  
  
int main()  
{  
    shared_ptr<A> ptrA = make_shared<A>();
    shared_ptr<B> ptrB = make_shared<B>();  
    ptrA->ptrA_B = ptrB;  
    ptrB->ptrB_A = ptrA;  
}  

上述代码运行的输出结果是:

调用class B的构造函数
调用class A的构造函数
调用class A的析构函数
调用class B的析构函数

7、使用智能指针是否会影响到程序的执行效率?

       使用智能指针不会影响到程序的执行效率。智能指针的设计原则是在内存和性能上尽可能高效。 例如,unique_ptr中的唯一数据成员是封装的指针。 从内存占用上看,unique_ptr 与该指针的大小完全相同,不是四个字节就是八个字节。从性能上看,使用重载了 * 和 ->运算符的智能指针访问封装指针的速度不会明显慢于直接访问原始指针的速度。

8、有必要学习C++11标准中的新特性

       2011年发布的C++11新标准,给C++引入了大量的新特性,是C++发展史上一次里程碑式的更新,开启了现代C++的时代!unique_ptr、shared_ptr和weak_ptr智能指针就是在这次更新中引入的!

       为什么说我们很有必要学习C++11标准中的新特性呢?主要从两点来看。一方面,现在很多公司在招聘C++开发人员时会频繁地问到C++11的新特性另一方面,很多开源代码在频繁地使用C++11的新特性,比如很多公司都在用的开源WebRTC库,就大量地使用到了C++11及C++14中的新特性,我们要阅读这些开源代码,必须要了解C++新特性。

       C++新标准引入的新特性,使得C++变得更加灵活,但也使得C++变得更加臃肿,更加难以驾驭!C++这些新特性,能真正驾驭的人并不多,所以为了保证代码的可读性与可维护性,在一般公司的项目代码中C++新特性用的并不多,一般只会用到少部分特性,比如一些新增的关键字和匿名函数(lamda表达式)等。

9、最后

       本文详细地介绍了C++11标准中引入的智能指针unique_ptr、shared_ptr和weak_ptr基础部分的内容,希望能给大家提供的一定的借鉴和参考。后面将介绍在代码中如何有效地使用这些智能指针。文章来源地址https://www.toymoban.com/news/detail-473857.html

到了这里,关于C++11中的智能指针unique_ptr、shared_ptr和weak_ptr详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C++11补充:智能指针如std::unique_ptr如何添加自定义的deleter

    关于智能指针的问题,有时候为了方便,需要在析构时附加一些清理操作,或者,有的指针本身来自C的库文件中,这时候,就非常期望能够使用自定义的deleter, 但是标准C++创建函数如std::make_unique / std::make_shared 等不支持创建带有自定义deleter的智能指针,这时,我们只能使用

    2024年02月07日
    浏览(32)
  • 智能指针shared_ptr

    shared_ptr共享它指向的对象,内部采用计数机制来实现。当新的shared_ptr与对象关联时,引用计数加1;当shared_ptr超出作用域时,引用计数减1;当引用计数为0时,释放该对象; shared_ptrA p0 = std::make_sharedA(\\\"西红柿\\\");//C++11提供 重载了*和-操作符,可以像使用指针一样使用shared_ptr

    2023年04月23日
    浏览(31)
  • 【cmu15445c++入门】(8)C++ 智能指针unique_ptr

    智能指针是一种数据结构,用于没有内置内存管理的语言(例如 C++)中的内存管理(有时还有其他功能)。内置内存管理的语言的指的是具有垃圾回收功能的语言,如Java、Python。 现代C++标准库的两个智能指针(以及您将在类中使用的智能指针)是 std::unique_ptr 和 std::shared_

    2024年02月20日
    浏览(29)
  • C++智能指针shared_ptr详解

    C++智能指针shared_ptr是一种可以自动管理内存的智能指针,它是C++11新增的特性之一。与传统指针不同,shared_ptr可以自动释放所管理的动态分配对象的内存,并避免了手动释放内存的繁琐操作,从而减少了内存泄漏和野指针的出现。 shared_ptr是一个模板类,通过引用计数器实现

    2023年04月22日
    浏览(30)
  • C++智能指针shared_ptr用法

    写在前面的总结: 一个shared_ptr对象管理一个指针(new T,在堆空间),多个shared_ptr对象可以管理同一个指针,只有某个shared_ptr对象第一次初始化指针时才执行指针的构造函数,管理同一个指针的shared_ptr对象个数称为引用计数,这个引用计数保存在每个管理该指针的shared_p

    2024年02月03日
    浏览(46)
  • C++智能指针shared_ptr使用详解

    shared_ptr 是一个共享所有权的智能指针,允许多个指针指向同一个对象。 ​ shared_ptr 使用 引用计数 ,每一个shared_ptr的拷贝都指向相同的内存。每使用它一次,内部的引用计数加1,每析构一次,内部的引用计数减1,减为0时,释放所指向的堆内存。shared_ptr内部的引用计数是安

    2024年02月07日
    浏览(34)
  • 【C++入门到精通】智能指针 auto_ptr、unique_ptr简介及C++模拟实现 [ C++入门 ]

    在 C++ 中,智能指针是一种非常重要的概念,它能够帮助我们自动管理动态分配的内存,避免出现内存泄漏等问题。在上一篇文章中,我们了解了智能指针的基本概念和原理, 本篇文章将继续介绍 auto_ptr 和 unique_ptr 两种智能指针的概念及其在 C++ 中的模拟实现 。通过学习这些

    2024年01月19日
    浏览(53)
  • C++之weak_ptr与shared_ptr智能指针实例(一百九十五)

    简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏: Audio工程师进阶系列 【 原创干货持续更新中…… 】🚀 人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药. 更多原创,欢迎关注:An

    2024年02月09日
    浏览(51)
  • 【C++入门到精通】智能指针 shared_ptr 简介及C++模拟实现 [ C++入门 ]

    在 C++ 动态内存管理中,除了 auto_ptr 和 unique_ptr 之外,还有一种 智能指针 shared_ptr ,它可以让多个指针共享同一个动态资源,并且能够自动释放资源。 shared_ptr 通过引用计数的方式来管理内存,能够避免程序中出现悬空指针和内存泄漏等问题 。本文将介绍 shared_ptr 的简介和

    2024年01月22日
    浏览(38)
  • 论 shared_ptr的线程安全

    今天有同事问我shared_ptr是线程更安全的吗?我当时脑子一懵,有点不确定。 但回过神来仔细一想这什么鸟问题,c++ stl里有线程安全的吗,shared_ptr 也不是针对线程安全而设计出来的呀,八竿子打不着的东西为什么会凑在一起问。 好像也就一个atmoic引用计数可以沾上边。 首先

    2024年02月08日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包