程序员

智能指针

2020-12-22  本文已影响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返回一个临时对象,赋值完成后将被销毁。

上一篇下一篇

猜你喜欢

热点阅读