c++标准库智能指针:shared_ptr

《c++ primer》12.1章节

1、智能指针是为了更加安全(防止内存还被引用着就被释放)和方便(不必自己手动释放内存)地使用动态内存(静态内存和栈内存中的对象由编译器创建和销毁,动态内存由程序创建和销毁)而存在。

2、shared_ptr的特点是允许多个指针指向同一个对象。

3、智能指针也是模板,因此要指定类型:

    std::shared_ptr<int> p;

4、shared_ptr默认值是nullptr。

5、unique()内存是否被唯一指针引用。

6、use_count()获取引用计数。当引用计数变为0时,shared_ptr会自动释放它管理的对象。

7、不能将普通指针转换成智能指针。

以下写法是错误的:

    std::shared_ptr<int> p1 = new int(1024);

new运算符返回的是一个int类型的指针,这里试图将int*普通指针隐式转换成shared_ptr。

正确的写法:

    std::shared_ptr<int> p1(new int(1024));

或:

    std::shared_ptr<int> p1 = std::make_shared<int>(1024);

8、重设shared_ptr,若再没有其他shared_ptr指向对象则对象释放:reset(),这会让shared_ptr的值设为空。

#define debug qDebug()<<
int main(int argc, char *argv[])
{
    std::shared_ptr<int> p1 = std::make_shared<int>(1024);
    std::shared_ptr<int> p2 = p1;
    debug (p1 == nullptr) << &*p1 << &*p2;
    p1.reset();
    debug (p1 == nullptr);
    debug p2.use_count() << *p2 << &*p2;
}

reset()还可以将一个新的指针赋给shared_ptr,如果原来指向的对象不为空,则被释放:

    std::shared_ptr<int> p1 = std::make_shared<int>(1024);
    p1.reset(new int(666));

9、get()返回智能指针管理的对象的普通指针,get()的存在是为了向不能使用智能指针的代码传递普通指针。

    std::shared_ptr<int> p1 = std::make_shared<int>(1024);
    int * p2 = p1.get();

10、不要混用普通指针和智能指针,例:

void debugValue(std::shared_ptr<int> sp)
{
    qDebug()<<*sp;
}

#define debug qDebug()<<
int main(int argc, char *argv[])
{
    int * p2 = new int(666);
    debugValue(std::shared_ptr<int>(p2));
    debug *p2;
}

这里传参数的时候创建了一个临时的shared_ptr,引用了p2的地址,当debugValue()执行完了以后会清除该临时变量,作为唯一引用p2地址的shared_ptr被清除时,会释放其引用的对象,p2指向的对象就被释放了。

正确的做法是只使用智能指针:

void debugValue(std::shared_ptr<int> sp)
{
    qDebug()<<*sp;
}

#define debug qDebug()<<
int main(int argc, char *argv[])
{
    std::shared_ptr<int> p1 = std::make_shared<int>(1024);
    debugValue(p1);
    if(p1 == nullptr)
        debug "p1为空";
    else
        debug *p1;
}

11、自定义删除器。 shared_ptr在清空所指向的对象时默认调用的是对象的析构函数,如果没有析构函数的对象可以在shared_ptr创建时指定自定义的删除器,如源码所示:

void deleteFun(int *p)
{
    qDebug()<<"delete Run";
    delete p;
}

#define debug qDebug()<<
int main(int argc, char *argv[])
{
    std::shared_ptr<int> p1(new int(1024),deleteFun);
}

这样清除对象时就会调用指定的函数。

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 书香水墨 设计师:CSDN官方博客 返回首页