C++11之智能指针(unique_ptrshared_ptrweak_ptrauto_ptr)浅谈内存管理

Posted 林夕07

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++11之智能指针(unique_ptrshared_ptrweak_ptrauto_ptr)浅谈内存管理相关的知识,希望对你有一定的参考价值。

目录

前言

下面这段代码看起来正常,但事实在特殊情况下f函数可能无法释放这个a资源。

void f()

	A * a = new A();
	...
	delete a;

例如:

  1. 如果在中间这段代码中有一个过早的return语句,且刚好被执行那么就会出现内存泄漏,这时你可能会说在每个return前都加一个delete a;语句。不得不说这种做法可以避免上述出现的问题,但会导致代码中随处可见的delete a;语句显得很乱且臃肿。
  2. 如果在中间这段代码中出现一个异常,也会导致内存泄漏。

单纯靠着delete a;语句去释放内存是行不通的。

智能指针

这时就要用到智能指针这个东西了。自动释放内存

  1. 智能指针会帮程序员来管理对象。
  2. 在智能智能释放时自动会调用所管理对象的析构函数。

头文件:memory

使用方法

虽然智能指针种类较多但是用法都一样,下面以unique_ptr为例。在申请到内存时将会交给unique_ptr接管,在执行完f函数后a对象将会自动调用析构函数。

void f()

    ...
	std::unique_ptr<A> a(new  A());
	...

unique_ptr

对象的所有权可以从一个独占指针转移到另一个指针,
转移方式:对象始终只能有一个指针作为其所有者。
当独占指针离开其作用域或将要拥有不同的对象时,它会自动释放自己所管理的对象。

实现unique_ptr类

template<class T>
class Unique_ptr

public:
    Unique_ptr(T* ptr)
    
        this->ptr = ptr;
    
    ~Unique_ptr()
    
        if (ptr != nullptr)
        
            delete ptr;
            cout << "释放ptr对象" << endl;
            ptr = nullptr;
        
    
    T& operator*()
    
        return *ptr;
    
    T* get()
    
        return ptr;
    
    T* operator->()
    
        return ptr;
    
private:
    Unique_ptr(const Unique_ptr& other) = delete;
    Unique_ptr& operator=(const Unique_ptr& other) = delete;
private:
    T* ptr;
;

使用uniquePtr

int main()

    unique_ptr<string> p1(new string("hellow"));
    cout << *p1 << endl;
    *p1 = "你好!";
    cout << *p1 << endl;
    return 0;

shared_ptr

共享指针将记录有多少个指针共同享有某个对象的所有权。当有更多指针被设置为指向该对象时,引用计数随之增加;当指针和对象分离时,则引用计数也相应减少。当引用计数降低至0时,该对象被删除。

实现SharedPtr

template<class T>
class SharedPtr

public:
    SharedPtr(T* ptr = nullptr)
    
        count = new int(1);
        this->ptr = ptr;
    
    SharedPtr(SharedPtr& other)
    
        *other.count += 1;
        count = other.count;
        ptr = other.ptr;
    
    SharedPtr& operator=(SharedPtr& other)
    
        *other.count += 1;
        count = other.count;
        ptr = other.ptr;
        return *this;
    
    ~SharedPtr()
    
        --(*count);
        cout << *count << "\\t" << ptr << endl;
        if (ptr != nullptr && 0 == *count)
        
            cout << "释放!" << endl;
            delete ptr;
            ptr = nullptr;
            delete count;
            count = nullptr;
        
    
    T& operator*() const
    
        return *ptr;
    
    T* get() const
    
        return ptr;
    
    T* operator->() const
    
        return ptr;
    
    int use_count(void) const
    
        return *count;
    
    
private:
    T* ptr;
    int* count;
;

使用shared_ptr

int main()

    Shared_ptr<int> p1(new int);
    Shared_ptr<int> p2(p1);
    *p1 = 10;
 
    cout << *p1 << endl;
    cout << *p2 << endl;
 
    cout << p1.use_count() << endl;//获取当前引用个数
 
    return 0;

weak_ptr

C++11标准虽然将 weak_ptr 定位为智能指针的一种,但该类型指针通常不单独使用(没有实际用处),只能和shared_ptr类型指针搭配使用。甚至可以将 weak_ptr 类型指针视为 shared_ptr 指针的一种辅助工具,借助weak_ptr类型指针, 我们可以获取 shared_ptr 指针的一些状态信息,比如有多少指向相同的 shared_ptr 指针、shared_ptr 指针指向的堆内存是否已经被释放等等。

使用weak_ptr

class Test

public:
    Test()
    
        cout << "Test()" << endl;
    
    ~Test()
    
        cout << "~Test()" << endl;
    
    void Output() const
    
        cout << "Output()" << endl;
    
;
weak_ptr<Test> test()

    shared_ptr<Test> p(new Test);
    return p;

 
int main()

    weak_ptr<Test> w1 = test();
    shared_ptr<Test> s1 = w1.lock();//检查对象是否被释放
    cout << s1 << endl;
    if (s1)
    
        cout << "对象依旧存在!" << endl;
    
    else
    
        cout << "对象已被释放" << endl;
    
    return 0;


在Effective C++第13条款中也建议:如果想要手工释放资源,容易发送某些错误。使用这类智能指针往往能让程序员更少犯错。

以上是关于C++11之智能指针(unique_ptrshared_ptrweak_ptrauto_ptr)浅谈内存管理的主要内容,如果未能解决你的问题,请参考以下文章

C++11 unique_ptr智能指针详解

C++11之智能指针(unique_ptrshared_ptrweak_ptrauto_ptr)浅谈内存管理

C++11之空指针-nullptr

C11新特性之智能指针

智能指针之 auto_ptr

智能指针11