学习C++ primer 之路 - ( 第十六章 之 智能指针)

先来看一个例子:

void remodel(std::string & str)
{
    std::string * px = new std::string(str);
    ...
    str = ps;
    return;
}

你是不是似乎发现了什么呢?(手动滑稽)没错,这个函数在返回时没有delete释放动态创建的内存。这种情况下大概是“忘记了“吧。那么 再看这个例子:

void remodel(std::string & str)
{
    std::string * ps = new std::string(str);
    ...
    if(weird_thing())
        throw exeption()    //抛出异常
    str = ps;
    delete ps;
    return;
}

你可能会想为什么不在抛出异常之前就delete?可以,没有问题,但是这不是长久之计,为什么?because 如果你忘了呢?在大的项目中如果忘记释放将可能带来严重后果,不能只靠记忆性delete来释放内存。

因此C++11引入新的指针来避免忘记释放的问题:智能指针.

介绍三个智能指针模板(auto_ptr、unique_ptr、shared_ptr):

所有的智能指针的使用都是要包含头文件<memory.h>

一、auto_ptr

那么例子将会之这样:

void remodel(std::string & str)
{
    auto_ptr<std::string>ps(new std::string(str));
    ...
    if(weird_thing())
        throw exeption()    //抛出异常
    str = *ps;
    return;
}

这样就不用使用delete了,他将自动的释放掉动态创建的内存。

这些智能指针模板都是位于名称空间std中,

但是为什么C++摒弃了auto_ptr呢?

像这样:

auto_ptr<string>films[1] = {auto_ptr<string>(new string("Fowl Balls"))};
auto_ptr<string>pwin;
pwin = films[0];    //将所有权转移给了pwin
cout << *fims[0] << endl;    //这样做会报错

上面例子表明auto_ptr是由所有权(所有人依法对自己财产所享有的占有使用收益处分的权利)模型的,当一个auto_ptr将自己赋值给另一个智能指针后,自己所有东西就赋予了被赋值的指针。自己就无权访问任何信息。(PS:反正我是这么理解的)(所有权被剥夺,这是件好事,可以防止两个析构函数视图删除一个对象)

所以C++摒弃了它(因为使用它后不能将两个指针指向同一个对象(地址))。

将auto_ptr写成shared_ptr就可以正常运行!

二、unique_ptr

可以说unique_ptr就是auto_ptr的升级版智能指针,它依然也是有所有权模型的,同样上述例子它依然是报错的,但是它会在编译器阶段报错,这是很不错的,至少比起在运行阶段。

unique_ptr是安全的可靠地

总之,党程序试图将一个 unique_ptr 赋值给另一个时,如果源 unique_ptr 是个临时右值,编译器允许这么做;如果源 unique_ptr 将存在一段时间,编译器将禁止这么做

三、shared_ptr

shared_ptr 是一个标准的共享所有权的智能指针, 允许多个指针指向同一个对象. 定义在 memory 文件中(非memory.h), 命名空间为 std.

  shared_ptr 是为了解决 auto_ptr 在对象所有权上的局限性(auto_ptr 是独占的), 在使用引用计数的机制上提供了可以共享所有权的智能指针, 当然这需要额外的开销:
  (1) shared_ptr 对象除了包括一个所拥有对象的指针外, 还必须包括一个引用计数代理对象的指针.
  (2) 时间上的开销主要在初始化和拷贝操作上, *和->操作符重载的开销跟auto_ptr是一样.
  (3) 开销并不是我们不使用shared_ptr的理由, 永远不要进行不成熟的优化, 直到性能分析器告诉你这一点.

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

最重要的要记住:

使用new 分配内存时,才能使用auto_ptr和shared_ptr,使用new[ ]分配内存时,不能使用它们。不使用new分配内存时,不能使用auto_ptr或者shared_ptr;不适用new或new[ ]分配内存时,不能使用unique_ptr。  

猜你喜欢

转载自blog.csdn.net/z1455841095/article/details/82629828