智能指针

作者: 骑猪满天飞 | 来源:发表于2020-12-22 19:35 被阅读0次

    智能指针介绍

    当我们在使用new动态分配内存时,有时候会忘记将分配的内存释放,例如,一个常规指针p,当p过期时p占据的内存将被释放,如果此前没有调用delete释放p指向的内存,就会导致内存泄漏。

    如果指针p是一个对象的话,那么就能够在p被删除时,调用它的析构函数去释放p指向的内存,从而简化了动态内存管理,这就是智能指针的思想。

    使用智能指针

    在头文件memory中定义了智能指针模板类:auto_ptr,unique_ptr,shared_ptr。(auto_ptr在C++11中被摒弃)

    shared_ptr有一个如下构造函数,接受一个指针作为参数:

    template <class U> 
    explicit shared_ptr (U* p)
    

    因此可以将new获得的地址,赋值给智能指针对象,来创建一个智能指针:

    shared<string> p(new string);
    

    此构造函数为explicit所以不支持隐式转换:

    shared<string> p;
    string* s = new string;
    p = s //隐式转换不支持,这是错误的
    

    智能指针的操作与常规指针类似,使用(*p),下面为智能指针使用演示程序:

    class Person {
    private:
        std::string name;
    public:
        Person(const std::string& s):name(s){}
        ~Person() { std::cout << "Object delete" << std::endl; }
        void view()const { std::cout << "Name: " << name << std::endl; }
    };
    
    int main() {
        {
            std::shared_ptr<Person> ps(new Person("Tom"));
            ps->view(); 
        }
        {
            std::unique_ptr<Person> pu(new Person("Bob"));
            pu->view();
        }
    }
    
    result.png

    当智能指针过期时,调用了它的析构函数,来释放Person对象。

    智能指针使用注意事项

    现在考虑两个智能指针指向同一块内存的情况,当两个指针都过期时,程序将释放同一块内存两次。

    为解决这个问题shared_ptr采用以下措施:

    跟踪引用特定对象的智能指针数(引用计数)。仅当最后一个指针过期时,才调用delete。

    unique_ptr的解决方案:

    建立所有权概念,对于特定的对象,只有一个智能指针可以拥有它,只有拥有对象的智能指针才可以释放它。并且,赋值操作将转让所有权,转让所有权后指针不再指向有效数据。这个过程将会非常严格。

    下面是unique_ptr处理此问题的两个例子:

    unique_ptr<string> p1(new string("unique"));    //#1
    unique_ptr<string> p2;                          //#2
    p2 = p1;                                        //#3  非法语句
    
    

    对于上述例子,转让所有权后p1将不再指向有效数据,为了避免p1不再指向有效数据,对于语句#3编译器将会认为是非法的

    假设又如下函数定义:
    
    unique_ptr<string>  demo(){
        std::unique_ptr<string> p(new string("dome"));
        return p;
    }
    unique_ptr<string> p2;  
    p2 = demo();
    

    这时p2 = demo()将是合法的赋值操作,因为demo返回一个临时对象,赋值完成后将被销毁。

    相关文章

      网友评论

        本文标题:智能指针

        本文链接:https://www.haomeiwen.com/subject/gbzsnktx.html