欢迎使用CSDN-markdown编辑器

来源:互联网 发布:程氏cms 编辑:程序博客网 时间:2024/06/05 18:55

智能指针指南
什么是智能指针?
智能指针是一种特定类型的“作用域对象”。它们就像常规指针,但是当它们超出范围时,可以自动释放它们指向的对象。由于C ++不是垃圾回收语言,所以这种功能很重要。-在确定范围对象用于自动管理堆分配对象的生存期被称为RAII(Resource AcquisitionIs Initialization)
这里有一些示例使用std::unique_ptr<>,最常见的智能指针类型:

// We can put a pointer into a std::unique_ptr<> at construction time...std::unique_ptr value(base::JSONReader::Read(data));std::unique_ptr foo_ptr(new Foo(...));// ...or by using reset(). std::unique_ptr bar_ptr;      // Like "Bar* bar_ptr = nullptr;". bar_ptr.reset(new Bar(...));  // Now |bar_ptr| is non-nullptr and owns the object.// We can test the std::unique_ptr<> directly. if (!value)   return false;// get() accesses the raw pointer underneath. Foo* raw_ptr = foo_ptr.get();// We can call through the std::unique_ptr<> as if it were a raw pointer. DictionaryValue* dict; if (!value->GetAsDictionary(&dict))   return false;

为什么要使用它们?
智能指针确保我们正确地销毁对象,即使它的创建和破坏被广泛地隔离(widely separated)。通过确保无论存在多少个不同的退出路径,本地对象都将被正确的清理,从而使功能更简单和安全。它们有助于在任何给定的时间强制一个对象拥有另一个对象,从而防止泄漏和双重释放。最后,他们的使用在功能调用中明确了预期中的所有权转让。
什么类型的智能指针存在?
Chromium中的两个常见智能指针是std::unique_ptr<>和scoped_refptr<>。前者用于单独拥有的对象,而后者用于引用计数对象(尽管通常你应该避免这些对象 - 见下文)。如果您熟悉C ++ 11, scoped_refptr<>则意图类似std::shared_ptr<>。
基础/记忆/还有一些其他感兴趣的对象:
linked_ptr<>是一个被弃用的对象,主要用于将容器中的智能指针存储在C ++ 11之前。现在Chromium支持C ++ 11,你不应该使用这个; std::unique_ptr<>直接存放在容器中(见下文)。
ScopedVector<>也被弃用; 这是一个拥有它包含的对象的向量。使用std::vector

// Foo() takes ownership of |bar|.void Foo(std::unique_ptr<Bar> bar);...std::unique_ptr<Bar> bar_ptr(new Bar());Foo(std::move(bar_ptr));          // After this statement, |bar_ptr| is null.Foo(std::unique_ptr<Bar>(new Bar()));  // No need to use std::move() on temporaries.

如果一个函数返回一个std::unique_ptr<>,那意味着调用者拥有返回的对象的所有权。的使用std::move()而返回的对象时,才需要如果函数的返回类型从本地变量的类型而不同。

class Base { ... };class Derived : public Base { ... };// Foo takes ownership of |base|, and the caller takes ownership of the returned// object.std::unique_ptr<Base> Foo(std::unique_ptr<Base> base) {  if (cond) {    return base;                           // Transfers ownership of |base| back to                                           // the caller.  }  // Note that on these next codepaths, |base| is deleted on exit.  if (cond2) {    return std::unique_ptr<Base>(new Base()));  // No std::move() necessary on temporaries.  }  std::unique_ptr<Derived> derived(new Derived());  return std::move(derived);               // Note that std::move() is necessary because                                           // type of |derived| is different from the return                                           // type of the function.}

如果一个函数接收或返回一个原始指针,可能意味着没有所有权转移,也可能不会。许多Chromium是在std::unique_ptr<>存在之前写的,或者是由不熟悉使用它来指示所有权转让的人员编写的,因此需要或返回原始指针,但是在该过程中转移所有权。因为编译器无法在这里强制执行正确的行为,所以不太安全。考虑清理这些代码,使得采用或返回原始指针的函数从不转移所有权。
通过引用传递或返回智能指针呢?
不要这样做
原则上,将const std :: unique_ptr &传递给不拥有所有权的函数比传递T *有一些优点:
调用者不能意外地传递一个完全虚伪的东西(例如int转换为一个T*),并且调用者被迫保证对象在整个函数调用中保持不变。但是,这个声明也会强制调用者将堆栈中的对象进行堆分配,即使它们可以在堆栈上声明它们。传递诸如原始指针的参数将所有权问题与分配问题分离,因此该函数仅仅表示对前者的偏好。为了简单和一致,我们避免要求作者平衡这些权衡,简单地说总是使用原始指针。
一个例外是使用与在智能指针的容器上操作的STL算法的lambda函数; 为了编译这些可能需要采取例如const std::unique_ptr&这种方式。说到这个…
我想使用一个STL容器来保存指针。我可以使用智能指针吗?
是! 从C ++ 11开始,您可以将智能指针存储在STL容器中。特别是,不再需要使用ScopedVector,因为您可以使用std::vector

0 0
原创粉丝点击