C++--智能指针

07-10 1039阅读

C++--智能指针

普通指针创建动态内存的问题:

1.new和new[]的内存需要使用delete和delete []释放。

2.有时忘记释放内存。

3.不知该在何时释放内存。

智能指针的优点:

在不需要对象时自动释放对象,从而避免内存泄漏和其他与内存管理相关的问题。

智能指针有:unique_ptr,shared_ptr和weak_ptr

C++中几种常见的智能指针

std::unique_ptr

独占所有权:unique_ptr 拥有其所指向对象的独占所有权。同一时间内只能有一个 unique_ptr 指向某个对象。

移动语义:当 unique_ptr 被赋值或移动到另一个 unique_ptr 时,原 unique_ptr 会失去对对象的所有权,而新 unique_ptr 会获得所有权。

自定义删除器:可以为 unique_ptr 指定一个自定义的删除器,以在删除对象时执行特定的操作。

不支持复制操作:由于 unique_ptr 拥有独占所有权,因此它不支持复制构造函数和复制赋值操作符。


std::shared_ptr

共享所有权:多个 shared_ptr 可以指向同一个对象,并共享其所有权。当最后一个拥有该对象的 shared_ptr 被销毁或重置时,对象才会被删除。

引用计数:shared_ptr 使用引用计数来跟踪指向某个对象的 shared_ptr 的数量。当引用计数变为0时,对象会被自动删除。

循环引用问题:由于 shared_ptr 的共享所有权特性,如果不当使用可能会导致循环引用问题,从而阻止对象被正确删除。为了解决这个问题,可以使用 std::weak_ptr。


std::weak_ptr

弱引用:weak_ptr 是对 shared_ptr 所管理对象的弱引用,它不增加对象的引用计数。因此,它不会阻止对象被 shared_ptr 删除。

解决循环引用:weak_ptr 通常用于解决由 shared_ptr 引起的循环引用问题。通过使用 weak_ptr 代替其中一个 shared_ptr,可以确保在循环引用中至少有一个指针不会增加引用计数。

访问原始指针:虽然 weak_ptr 本身不拥有对象,但它可以安全地访问对象的原始指针(通过调用 lock() 方法)。如果对象仍然存在,lock() 将返回一个指向该对象的 shared_ptr;否则,将返回一个空的 shared_ptr。

以下是一些可能导致内存泄漏的情况:

循环引用:在使用std::shared_ptr时,如果两个或更多的智能指针相互持有对方的引用(形成循环),则它们将永远不会被释放,从而导致内存泄漏。为了避免这种情况,可以使用std::weak_ptr来打破循环。

自定义删除器:如果你为智能指针提供了一个自定义删除器,并且这个删除器存在缺陷,那么可能会导致内存泄漏。例如,删除器可能只是简单地调用delete,但如果你的对象需要特殊的清理逻辑(如关闭文件句柄或释放其他资源),那么这些资源可能不会被正确释放。


unique_ptr

unique_ptr 独占智能指针。

它独占指向的对象,也就是说,某个时刻只有一个 unique_ptr 指向一个给定对象,当unique_ptr 被销毁时,它所指向的对象也被销毁。

需要包含头文件: #include

class Student
{
public:
    string m_name;//学生姓名
    Student(const string& name = "") :m_name(name)//构造函数
    {
        cout 
        cout 
    auto p1 = new Student("刘备");//利用new创建一个新对象
    //delete p1; //忘记释放对象,出现内存泄漏
    return 0;
}

public:
    unique_ptr( );               //默认构造函数
    explicit unique_ptr( pointer Ptr ); //构造函数,不允许隐式转换
    unique_ptr (pointer Ptr, typename remove_reference
public:
    Student(const string& name = ""):m_name(name)//构造函数
    {
        cout 
        cout 
        cout 
    Student* p1 = new Student("刘备");
    unique_ptr
    cout 
    unique_ptr
    cout 
public:
    void operator()(Student* ps) //重载()
    {
        cout 
    cout 
    //自定义删除器,普通函数  
    unique_ptr
public:
    Student(const string& name = ""):m_name(name)//构造函数
    {
        cout 
        cout 
        cout 
    //方法一:
    shared_ptr
    p-show();
}
void test02(shared_ptr
    p-show();
}
int main()
{
    shared_ptr
    cout 
public:
    void operator()(Student* ps) //重载()
    {
        cout 
    cout 
    shared_ptr
public:
    A(){
        m_a = new int[10];//动态创建10个元素
        cout 
        delete[]m_a;//释放内存
        cout 
public:
    shared_ptr
        m_b = new int[10];//动态创建10个元素
        cout 
        delete[]m_b;//释放内存
        cout 
    auto a = std::make_shared
public:
    A(){
        m_a = new int[10];//动态创建10个元素
        cout 
        delete[]m_a;//释放内存
        cout 
public:
    shared_ptr
        m_b = new int[10];//动态创建10个元素
        cout 
        delete[]m_b;//释放内存
        cout 
    auto a = std::make_shared
VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]