C++ 什么是智能指针,什么时候应该使用?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/106508/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 12:53:51  来源:igfitidea点击:

What is a smart pointer and when should I use one?

c++pointersc++11smart-pointersc++-faq

提问by Alex Reynolds

What is a smart pointer and when should I use one?

什么是智能指针,什么时候应该使用?

回答by Lloyd

UPDATE

更新

This answer is rather old, and so describes what was 'good' at the time, which was smart pointers provided by the Boost library. Since C++11, the standard library has provided sufficient smart pointers types, and so you should favour the use of std::unique_ptr, std::shared_ptrand std::weak_ptr.

这个答案相当陈旧,因此描述了当时什么是“好”,即 Boost 库提供的智能指针。从 C++11 开始,标准库提供了足够多的智能指针类型,因此您应该倾向于使用std::unique_ptr,std::shared_ptrstd::weak_ptr

There was also std::auto_ptr. It was very much like a scoped pointer, except that it also had the "special" dangerous ability to be copied — which also unexpectedly transfers ownership.
It was deprecated in C++11 and removed in C++17, so you shouldn't use it.

也有std::auto_ptr。它非常像一个作用域指针,除了它还有“特殊”危险的复制能力——这也意外地转移了所有权。
它在 C++11 中被弃用并在 C++17 中删除,所以你不应该使用它。

std::auto_ptr<MyObject> p1 (new MyObject());
std::auto_ptr<MyObject> p2 = p1; // Copy and transfer ownership. 
                                 // p1 gets set to empty!
p2->DoSomething(); // Works.
p1->DoSomething(); // Oh oh. Hopefully raises some NULL pointer exception.


OLD ANSWER

旧答案

A smart pointer is a class that wraps a 'raw' (or 'bare') C++ pointer, to manage the lifetime of the object being pointed to. There is no single smart pointer type, but all of them try to abstract a raw pointer in a practical way.

智能指针是一个包装“原始”(或“裸”)C++ 指针的类,用于管理所指向对象的生命周期。没有单一的智能指针类型,但它们都试图以一种实用的方式抽象一个原始指针。

Smart pointers should be preferred over raw pointers. If you feel you need to use pointers (first consider if you reallydo), you would normally want to use a smart pointer as this can alleviate many of the problems with raw pointers, mainly forgetting to delete the object and leaking memory.

智能指针应该优于原始指针。如果你觉得你需要使用指针(首先考虑你是否真的这样做了),你通常会想要使用智能指针,因为这可以缓解原始指针的许多问题,主要是忘记删除对象和内存泄漏。

With raw pointers, the programmer has to explicitly destroy the object when it is no longer useful.

使用原始指针,程序员必须在对象不再有用时显式销毁它。

// Need to create the object to achieve some goal
MyObject* ptr = new MyObject(); 
ptr->DoSomething(); // Use the object in some way
delete ptr; // Destroy the object. Done with it.
// Wait, what if DoSomething() raises an exception...?

A smart pointer by comparison defines a policy as to when the object is destroyed. You still have to create the object, but you no longer have to worry about destroying it.

相比之下,智能指针定义了有关何时销毁对象的策略。您仍然需要创建对象,但您不再需要担心销毁它。

SomeSmartPtr<MyObject> ptr(new MyObject());
ptr->DoSomething(); // Use the object in some way.

// Destruction of the object happens, depending 
// on the policy the smart pointer class uses.

// Destruction would happen even if DoSomething() 
// raises an exception

The simplest policy in use involves the scope of the smart pointer wrapper object, such as implemented by boost::scoped_ptror std::unique_ptr.

使用的最简单的策略涉及智能指针包装对象的范围,例如由boost::scoped_ptr或实现std::unique_ptr

void f()
{
    {
       std::unique_ptr<MyObject> ptr(new MyObject());
       ptr->DoSomethingUseful();
    } // ptr goes out of scope -- 
      // the MyObject is automatically destroyed.

    // ptr->Oops(); // Compile error: "ptr" not defined
                    // since it is no longer in scope.
}

Note that std::unique_ptrinstances cannot be copied. This prevents the pointer from being deleted multiple times (incorrectly). You can, however, pass references to it around to other functions you call.

请注意,std::unique_ptr无法复制实例。这可以防止多次(错误地)删除指针。但是,您可以将对其的引用传递给您调用的其他函数。

std::unique_ptrs are useful when you want to tie the lifetime of the object to a particular block of code, or if you embedded it as member data inside another object, the lifetime of that other object. The object exists until the containing block of code is exited, or until the containing object is itself destroyed.

std::unique_ptr当您想将对象的生命周期与特定的代码块联系起来,或者如果您将它作为成员数据嵌入另一个对象中时,s 很有用,即另一个对象的生命周期。该对象一直存在,直到退出包含代码块,或者直到包含对象本身被销毁。

A more complex smart pointer policy involves reference counting the pointer. This does allow the pointer to be copied. When the last "reference" to the object is destroyed, the object is deleted. This policy is implemented by boost::shared_ptrand std::shared_ptr.

更复杂的智能指针策略涉及对指针进行引用计数。这确实允许复制指针。当对对象的最后一个“引用”被销毁时,该对象将被删除。该政策由boost::shared_ptr和实施std::shared_ptr

void f()
{
    typedef std::shared_ptr<MyObject> MyObjectPtr; // nice short alias
    MyObjectPtr p1; // Empty

    {
        MyObjectPtr p2(new MyObject());
        // There is now one "reference" to the created object
        p1 = p2; // Copy the pointer.
        // There are now two references to the object.
    } // p2 is destroyed, leaving one reference to the object.
} // p1 is destroyed, leaving a reference count of zero. 
  // The object is deleted.

Reference counted pointers are very useful when the lifetime of your object is much more complicated, and is not tied directly to a particular section of code or to another object.

当对象的生命周期复杂得多,并且不直接绑定到特定代码段或另一个对象时,引用计数指针非常有用。

There is one drawback to reference counted pointers — the possibility of creating a dangling reference:

引用计数指针有一个缺点——创建悬空引用的可能性:

// Create the smart pointer on the heap
MyObjectPtr* pp = new MyObjectPtr(new MyObject())
// Hmm, we forgot to destroy the smart pointer,
// because of that, the object is never destroyed!

Another possibility is creating circular references:

另一种可能性是创建循环引用:

struct Owner {
   std::shared_ptr<Owner> other;
};

std::shared_ptr<Owner> p1 (new Owner());
std::shared_ptr<Owner> p2 (new Owner());
p1->other = p2; // p1 references p2
p2->other = p1; // p2 references p1

// Oops, the reference count of of p1 and p2 never goes to zero!
// The objects are never destroyed!

To work around this problem, both Boost and C++11 have defined a weak_ptrto define a weak (uncounted) reference to a shared_ptr.

为了解决这个问题,Boost 和 C++11 都定义了 aweak_ptr来定义对 a 的弱(不可计数)引用shared_ptr

回答by einpoklum

Here's a simple answer for these days of modern C++ (C++11 and later):

这是现代 C++(C++11 及更高版本)的这些天的简单答案:

  • What is a smart pointer?
    It's a type whose values can be used like pointers, but which provides the additional feature of automatic memory management: When a smart pointer is no longer in use, the memory it points to is deallocated (see also the more detailed definition on Wikipedia).
  • When should I use one?
    In code which involves tracking the ownership of a piece of memory, allocating or de-allocating; the smart pointer often saves you the need to do these things explicitly.
  • But which smart pointer should I use in which of those cases?
    • Use std::unique_ptrwhen you don't intend to hold multiple references to the same object. For example, use it for a pointer to memory which gets allocated on entering some scope and de-allocated on exiting the scope.
    • Use std::shared_ptrwhen you do want to refer to your object from multiple places - and do not want your object to be de-allocated until all these references are themselves gone.
    • Use std::weak_ptrwhen you do want to refer to your object from multiple places - for those references for which it's ok to ignore and deallocate (so they'll just note the object is gone when you try to dereference).
    • Don't use the boost::smart pointers or std::auto_ptrexcept in special cases which you can read up on if you must.
  • Hey, I didn't ask which one to use!
    Ah, but you really wanted to, admit it.
  • So when should I use regular pointers then?
    Mostly in code that is oblivious to memory ownership. This would typically be in functions which get a pointer from someplace else and do not allocate nor de-allocate, and do not store a copy of the pointer which outlasts their execution.
  • 什么是智能指针?
    它是一种其值可以像指针一样使用的类型,但它提供了自动内存管理的附加功能:当不再使用智能指针时,它指向的内存将被释放(另请参阅Wikipedia 上更详细的定义)。
  • 我应该什么时候使用?
    在涉及跟踪一块内存的所有权、分配或取消分配的代码中;智能指针通常可以让您无需明确地做这些事情。
  • 但是在哪些情况下我应该使用哪个智能指针?
    • 使用std::unique_ptr时,你不打算持有到同一对象的多个引用。例如,将它用作指向内存的指针,该指针在进入某个范围时被分配并在退出该范围时被取消分配。
    • std::shared_ptr当您确实想从多个地方引用您的对象时使用- 并且不希望您的对象在所有这些引用都消失之前被取消分配。
    • std::weak_ptr当您确实想从多个位置引用您的对象时使用- 对于那些可以忽略和取消分配的引用(因此当您尝试取消引用时,他们只会注意到该对象已消失)。
    • 不要使用boost::智能指针,或者std::auto_ptr除非在特殊情况下可以阅读,如果必须的话。
  • 嘿,我没有问用哪个!
    啊,但你真的很想,承认吧。
  • 那么我什么时候应该使用常规指针呢?
    主要是在无视内存所有权的代码中。这通常是在从其他地方获取指针并且不分配也不取消分配的函数中,并且不存储比执行时间更长的指针副本。

回答by sergtk

Smart pointeris a pointer-like type with some additional functionality, e.g. automatic memory deallocation, reference counting etc.

智能指针是一种类似指针的类型,具有一些附加功能,例如自动内存释放、引用计数等。

Small intro is available on page Smart Pointers - What, Why, Which?.

小介绍可在页面智能指针 - 什么,为什么,哪个?.

One of the simple smart-pointer type is std::auto_ptr(chapter 20.4.5 of C++ standard), which allows to deallocate memory automatically when it out of scope and which is more robust than simple pointer usage when exceptions are thrown, although less flexible.

一种简单的智能指针类型是std::auto_ptr(C++ 标准的第 20.4.5 章),它允许在超出范围时自动释放内存,并且在抛出异常时比简单的指针使用更健壮,尽管不太灵活。

Another convenient type is boost::shared_ptrwhich implements reference counting and automatically deallocates memory when no references to object remains. This helps avoiding memory leaks and is easy to use to implement RAII.

另一种方便的类型是boost::shared_ptr实现引用计数并在没有对对象的引用时自动释放内存。这有助于避免内存泄漏,并且易于用于实现RAII

Subject is covered in depth in book "C++ Templates: The Complete Guide" by David Vandevoorde, Nicolai M. Josuttis, chapter Chapter 20. Smart Pointers. Some topics covered:

David Vandevoorde、Nicolai M. Josuttis 合着的“C++ 模板:完整指南”一书对主题进行了深入介绍,第 20 章“智能指针”。涉及的一些主题:

回答by Sridhar Iyer

Definitions provided by Chris, Sergdev and Llyod are correct. I prefer a simpler definition though, just to keep my life simple: A smart pointer is simply a class that overloads the ->and *operators. Which means that your object semantically looks like a pointer but you can make it do way cooler things, including reference counting, automatic destruction etc. shared_ptrand auto_ptrare sufficient in most cases, but come along with their own set of small idiosyncrasies.

Chris、Sergdev 和 Llyod 提供的定义是正确的。不过,我更喜欢一个更简单的定义,只是为了让我的生活保持简单:智能指针只是一个重载->and*运算符的类。这意味着你的对象在语义上看起来像一个指针,但你可以让它做一些更酷的事情,包括引用计数、自动销毁等 shared_ptrauto_ptr并且在大多数情况下就足够了,但伴随着它们自己的一组小特性。

回答by markets

A smart pointer is like a regular (typed) pointer, like "char*", except when the pointer itself goes out of scope then what it points to is deleted as well. You can use it like you would a regular pointer, by using "->", but not if you need an actual pointer to the data. For that, you can use "&*ptr".

智能指针类似于常规(类型化)指针,如“char*”,除非指针本身超出范围,然后它指向的内容也会被删除。通过使用“->”,您可以像使用常规指针一样使用它,但如果您需要指向数据的实际指针,则不能使用它。为此,您可以使用“&*ptr”。

It is useful for:

它适用于:

  • Objects that must be allocated with new, but that you'd like to have the same lifetime as something on that stack. If the object is assigned to a smart pointer, then they will be deleted when the program exits that function/block.

  • Data members of classes, so that when the object is deleted all the owned data is deleted as well, without any special code in the destructor (you will need to be sure the destructor is virtual, which is almost always a good thing to do).

  • 必须使用 new 分配的对象,但您希望与该堆栈上的对象具有相同的生命周期。如果将对象分配给智能指针,则当程序退出该功能/块时,它们将被删除。

  • 类的数据成员,这样当对象被删除时,所有拥有的数据也会被删除,析构函数中没有任何特殊代码(您需要确保析构函数是虚拟的,这几乎总是一件好事) .

You may notwant to use a smart pointer when:

你可能希望使用智能指针时:

  • ... the pointer shouldn't actually own the data... i.e., when you are just using the data, but you want it to survive the function where you are referencing it.
  • ... the smart pointer isn't itself going to be destroyed at some point. You don't want it to sit in memory that never gets destroyed (such as in an object that is dynamically allocated but won't be explicitly deleted).
  • ... two smart pointers might point to the same data. (There are, however, even smarter pointers that will handle that... that is called reference counting.)
  • ...指针实际上不应该拥有数据......即,当您只使用数据时,但您希望它在您引用它的函数中继续存在。
  • ...智能指针本身不会在某个时候被销毁。您不希望它位于永远不会被销毁的内存中(例如在动态分配但不会被显式删除的对象中)。
  • ... 两个智能指针可能指向相同的数据。(但是,甚至有更智能的指针可以处理……这称为引用计数。)

See also:

也可以看看:

回答by Chris Jester-Young

Most kinds of smart pointers handle disposing of the pointer-to object for you. It's very handy because you don't have to think about disposing of objects manually anymore.

大多数类型的智能指针都会为您处理指向对象的指针。这非常方便,因为您不必再​​考虑手动处理对象了。

The most commonly-used smart pointers are std::tr1::shared_ptr(or boost::shared_ptr), and, less commonly, std::auto_ptr. I recommend regular use of shared_ptr.

最常用的智能指针是std::tr1::shared_ptr(或boost::shared_ptr),以及不太常见的std::auto_ptr. 我建议经常使用shared_ptr.

shared_ptris very versatile and deals with a large variety of disposal scenarios, including cases where objects need to be "passed across DLL boundaries" (the common nightmare case if different libcs are used between your code and the DLLs).

shared_ptr非常通用,可以处理各种各样的处理场景,包括对象需要“跨 DLL 边界传递”的情况(如果libc在代码和 DLL 之间使用不同的s,则是常见的噩梦情况)。

回答by Saqlain

A smart pointer is an object that acts like a pointer, but additionally provides control on construction, destruction, copying, moving and dereferencing.

智能指针是一个对象,它的作用类似于指针,但还提供对构造、销毁、复制、移动和取消引用的控制。

One can implement one's own smart pointer, but many libraries also provide smart pointer implementations each with different advantages and drawbacks.

可以实现自己的智能指针,但许多库也提供智能指针实现,每个实现都有不同的优点和缺点。

For example, Boostprovides the following smart pointer implementations:

例如,Boost提供了以下智能指针实现:

  • shared_ptr<T>is a pointer to Tusing a reference count to determine when the object is no longer needed.
  • scoped_ptr<T>is a pointer automatically deleted when it goes out of scope. No assignment is possible.
  • intrusive_ptr<T>is another reference counting pointer. It provides better performance than shared_ptr, but requires the type Tto provide its own reference counting mechanism.
  • weak_ptr<T>is a weak pointer, working in conjunction with shared_ptrto avoid circular references.
  • shared_array<T>is like shared_ptr, but for arrays of T.
  • scoped_array<T>is like scoped_ptr, but for arrays of T.
  • shared_ptr<T>T使用引用计数来确定何时不再需要对象的指针。
  • scoped_ptr<T>是超出范围时自动删除的指针。不可能分配。
  • intrusive_ptr<T>是另一个引用计数指针。它提供比 更好的性能shared_ptr,但需要该类型T提供自己的引用计数机制。
  • weak_ptr<T>是一个弱指针,与 一起工作shared_ptr以避免循环引用。
  • shared_array<T>就像shared_ptr,但对于T.
  • scoped_array<T>就像scoped_ptr,但对于T.

These are just one linear descriptions of each and can be used as per need, for further detail and examples one can look at the documentation of Boost.

这些只是每个的线性描述,可以根据需要使用,有关更多详细信息和示例,可以查看 Boost 的文档。

Additionally, the C++ standard library provides three smart pointers; std::unique_ptrfor unique ownership, std::shared_ptrfor shared ownership and std::weak_ptr. std::auto_ptrexisted in C++03 but is now deprecated.

此外,C++ 标准库提供了三个智能指针;std::unique_ptr对于唯一所有权、std::shared_ptr共享所有权和std::weak_ptr. std::auto_ptr存在于 C++03 中,但现在已弃用。

回答by Santosh

Here is the Link for similar answers : http://sickprogrammersarea.blogspot.in/2014/03/technical-interview-questions-on-c_6.html

这是类似答案的链接:http: //sickprogrammersarea.blogspot.in/2014/03/technical-interview-questions-on-c_6.html

A smart pointer is an object that acts, looks and feels like a normal pointer but offers more functionality. In C++, smart pointers are implemented as template classes that encapsulate a pointer and override standard pointer operators. They have a number of advantages over regular pointers. They are guaranteed to be initialized as either null pointers or pointers to a heap object. Indirection through a null pointer is checked. No delete is ever necessary. Objects are automatically freed when the last pointer to them has gone away. One significant problem with these smart pointers is that unlike regular pointers, they don't respect inheritance. Smart pointers are unattractive for polymorphic code. Given below is an example for the implementation of smart pointers.

智能指针是一个对象,它的行为、外观和感觉都像普通指针,但提供更多功能。在 C++ 中,智能指针被实现为封装指针并覆盖标准指针运算符的模板类。与常规指针相比,它们具有许多优点。它们保证被初始化为空指针或指向堆对象的指针。检查通过空指针的间接性。不需要删除。当指向它们的最后一个指针消失时,对象会自动释放。这些智能指针的一个重要问题是,与常规指针不同,它们不尊重继承。智能指针对于多态代码没有吸引力。下面给出了一个实现智能指针的例子。

Example:

例子:

template <class X>
class smart_pointer
{
          public:
               smart_pointer();                          // makes a null pointer
               smart_pointer(const X& x)            // makes pointer to copy of x

               X& operator *( );
               const X& operator*( ) const;
               X* operator->() const;

               smart_pointer(const smart_pointer <X> &);
               const smart_pointer <X> & operator =(const smart_pointer<X>&);
               ~smart_pointer();
          private:
               //...
};

This class implement a smart pointer to an object of type X. The object itself is located on the heap. Here is how to use it:

这个类实现了一个指向 X 类型对象的智能指针。对象本身位于堆上。以下是如何使用它:

smart_pointer <employee> p= employee("Harris",1333);

Like other overloaded operators, p will behave like a regular pointer,

像其他重载运算符一样,p 的行为就像一个普通的指针,

cout<<*p;
p->raise_salary(0.5);

回答by Jorge Ferreira

http://en.wikipedia.org/wiki/Smart_pointer

http://en.wikipedia.org/wiki/Smart_pointer

In computer science, a smart pointer is an abstract data type that simulates a pointer while providing additional features, such as automatic garbage collection or bounds checking. These additional features are intended to reduce bugs caused by the misuse of pointers while retaining efficiency. Smart pointers typically keep track of the objects that point to them for the purpose of memory management. The misuse of pointers is a major source of bugs: the constant allocation, deallocation and referencing that must be performed by a program written using pointers makes it very likely that some memory leaks will occur. Smart pointers try to prevent memory leaks by making the resource deallocation automatic: when the pointer to an object (or the last in a series of pointers) is destroyed, for example because it goes out of scope, the pointed object is destroyed too.

在计算机科学中,智能指针是一种抽象数据类型,它模拟指针同时提供附加功能,例如自动垃圾收集或边界检查。这些附加功能旨在减少因滥用指针而导致的错误,同时保持效率。为了内存管理的目的,智能指针通常会跟踪指向它们的对象。滥用指针是错误的主要来源:必须由使用指针编写的程序执行的常量分配、释放和引用使得很可能会发生一些内存泄漏。智能指针试图通过自动释放资源来防止内存泄漏:当指向一个对象(或一系列指针中的最后一个)的指针被销毁时,

回答by nnrales

Let T be a class in this tutorial Pointers in C++ can be divided into 3 types :

让 T 成为本教程中的一个类 C++ 中的指针可以分为 3 种类型:

1) Raw pointers:

1)原始指针

T a;  
T * _ptr = &a; 

They hold a memory address to a location in memory. Use with caution , as programs become complex hard to keep track.

它们保存内存中某个位置的内存地址。谨慎使用,因为程序变得复杂而难以跟踪。

Pointers with const data or address { Read backwards }

具有常量数据或地址的指针 { 向后读取 }

T a ; 
const T * ptr1 = &a ; 
T const * ptr1 = &a ;

Pointer to a data type T which is a const. Meaning you cannot change the data type using the pointer. ie *ptr1 = 19; will not work. But you can move the pointer. ie ptr1++ , ptr1--; etc will work. Read backwards : pointer to type T which is const

指向数据类型 T 的指针,它是一个常量。这意味着您不能使用指针更改数据类型。即*ptr1 = 19;不管用。但是您可以移动指针。即ptr1++ , ptr1--;等会起作用。向后阅读:指向类型 T 的指针,它是 const

  T * const ptr2 ;

A const pointer to a data type T . Meaning you cannot move the pointer but you can change the value pointed to by the pointer. ie *ptr2 = 19will work but ptr2++ ; ptr2--etc will not work. Read backwards : const pointer to a type T

指向数据类型 T 的 const 指针。这意味着您不能移动指针,但可以更改指针指向的值。即*ptr2 = 19会工作,但ptr2++ ; ptr2--等不会工作。向后阅读:指向类型 T 的 const 指针

const T * const ptr3 ; 

A const pointer to a const data type T . Meaning you cannot either move the pointer nor can you change the data type pointer to be the pointer. ie . ptr3-- ; ptr3++ ; *ptr3 = 19;will not work

指向 const 数据类型 T 的 const 指针。这意味着您既不能移动指针,也不能将数据类型指针更改为指针。IE 。ptr3-- ; ptr3++ ; *ptr3 = 19;不管用

3) Smart Pointers: { #include <memory>}

3)智能指针:{ #include <memory>}

Shared Pointer:

共享指针

  T a ; 
     //shared_ptr<T> shptr(new T) ; not recommended but works 
     shared_ptr<T> shptr = make_shared<T>(); // faster + exception safe

     std::cout << shptr.use_count() ; // 1 //  gives the number of " 
things " pointing to it. 
     T * temp = shptr.get(); // gives a pointer to object

     // shared_pointer used like a regular pointer to call member functions
      shptr->memFn();
     (*shptr).memFn(); 

    //
     shptr.reset() ; // frees the object pointed to be the ptr 
     shptr = nullptr ; // frees the object 
     shptr = make_shared<T>() ; // frees the original object and points to new object

Implemented using reference counting to keep track of how many " things " point to the object pointed to by the pointer. When this count goes to 0 , the object is automatically deleted , ie objected is deleted when all the share_ptr pointing to the object goes out of scope. This gets rid of the headache of having to delete objects which you have allocated using new.

实现使用引用计数来跟踪有多少“事物”指向指针所指向的对象。当此计数变为 0 时,该对象将被自动删除,即当所有指向该对象的 share_ptr 超出范围时,将删除 objected。这摆脱了必须删除使用 new 分配的对象的麻烦。

Weak Pointer :Helps deal with cyclic reference which arises when using Shared Pointer If you have two objects pointed to by two shared pointers and there is an internal shared pointer pointing to each others shared pointer then there will be a cyclic reference and the object will not be deleted when shared pointers go out of scope. To solve this , change the internal member from a shared_ptr to weak_ptr. Note : To access the element pointed to by a weak pointer use lock() , this returns a weak_ptr.

弱指针:帮助处理使用共享指针时出现的循环引用当共享指针超出范围时被删除。要解决此问题,请将内部成员从 shared_ptr 更改为 weak_ptr。注意:要访问弱指针指向的元素,请使用 lock() ,这将返回一个 weak_ptr。

T a ; 
shared_ptr<T> shr = make_shared<T>() ; 
weak_ptr<T> wk = shr ; // initialize a weak_ptr from a shared_ptr 
wk.lock()->memFn() ; // use lock to get a shared_ptr 
//   ^^^ Can lead to exception if the shared ptr has gone out of scope
if(!wk.expired()) wk.lock()->memFn() ;
// Check if shared ptr has gone out of scope before access

See : When is std::weak_ptr useful?

请参阅:std::weak_ptr 何时有用?

Unique Pointer :Light weight smart pointer with exclusive ownership. Use when pointer points to unique objects without sharing the objects between the pointers.

独特的指针:具有独家所有权的轻量级智能指针。当指针指向唯一对象而不共享指针之间的对象时使用。

unique_ptr<T> uptr(new T);
uptr->memFn(); 

//T * ptr = uptr.release(); // uptr becomes null and object is pointed to by ptr
uptr.reset() ; // deletes the object pointed to by uptr 

To change the object pointed to by the unique ptr , use move semantics

要更改唯一 ptr 指向的对象,请使用移动语义

unique_ptr<T> uptr1(new T);
unique_ptr<T> uptr2(new T);
uptr2 = std::move(uptr1); 
// object pointed by uptr2 is deleted and 
// object pointed by uptr1 is pointed to by uptr2
// uptr1 becomes null 

References : They can essentially be though of as const pointers, ie a pointer which is const and cannot be moved with better syntax.

引用:它们本质上可以被认为是 const 指针,即一个常量并且不能用更好的语法移动的指针。

See : What are the differences between a pointer variable and a reference variable in C++?

请参阅:C++ 中的指针变量和引用变量有什么区别?

r-value reference : reference to a temporary object   
l-value reference : reference to an object whose address can be obtained
const reference : reference to a data type which is const and cannot be modified 

Reference : https://www.youtube.com/channel/UCEOGtxYTB6vo6MQ-WQ9W_nQThanks to Andre for pointing out this question.

参考:https: //www.youtube.com/channel/UCEOGtxYTB6vo6MQ-WQ9W_nQ感谢安德烈指出这个问题。