【问题标题】:Assigning existing values to smart-ptrs?将现有值分配给智能指针?
【发布时间】:2026-02-07 20:00:01
【问题描述】:

我刚刚学习智能指针,但在将变量的预先存在位置分配给标准库的共享指针时遇到了麻烦。

例如,假设您有一个 int x,但您不知道它的值。使用普通指针,我只是这样做了

int* ptr;
ptr = &x;

我用共享指针尝试了这两种方法,并且

std::tr1::shared_ptr<int> ptr;
ptr = std::make_shared<int> (&x)

所以我不知道该怎么做。

【问题讨论】:

  • 您不太可能希望将变量的地址传递给共享指针。共享指针的意义在于它们管理动态分配的对象。

标签: c++ std shared-ptr tr1


【解决方案1】:

您不会(通常)将智能指针指向现有变量。智能指针管理动态分配对象的生命周期,使用后将其删除;如果它试图删除它,将它指向不是动态分配的东西会导致错误。

您通常会使用newmake_shared 来创建一个对象,并使用其结果创建或分配一个智能指针:

std::shared_ptr<int> ptr(new int(42)); // Create a new pointer to manage an object
ptr.reset(new int(66));                // Reset to manage a different object
ptr = std::make_shared<int>(53);       // Use `make_shared` rather than `new`

make_shared 通常比new 更可取,因为它可以更好地利用内存并提供更强的异常安全性。

【讨论】:

    【解决方案2】:

    共享指针用于管理动态分配的内存,更准确地说,它们管理此内存的所有权

    基本上,智能指针是Ressource Acquisition Is Initialization 或RAII 的具体化。我强烈建议你看看这个原则,因为它对于管理资源所有权非常有用(基本上,每次你需要获取资源并释放它,无论是内存、数据库连接、文件处理程序、互斥锁)等)。

    它所做的基本上是保证当有人指向它管理的动态分配的内存时,该内存将可用,并且一旦指向该内存的最后一个(智能)指针超出范围,然后delete被调用。

    然后,将智能指针与具有自动存储持续时间的变量一起使用是没有意义的(即,当它们超出范围或当它们所属的对象超出范围或被删除时(如果它是新的)。

    【讨论】:

      【解决方案3】:

      一旦shared_ptr的引用计数器达到零,对象就会被最后一个shared_ptr删除。使用智能指针,您可以指定删除该对象的函数。

      Deleter 是一个简单的函数(默认为通常的运算符 delete),它必须绑定到智能指针,可以通过模板参数静态绑定(请参阅unique_ptr),也可以通过构造函数参数动态绑定(请参阅shared_ptr)。

      // dynamically via shared_ptr:
      //   shared_ptrs share the pointer to the Deleter
      //   because they already share a common data structure for reference counting.
      auto ignore = [](int* o){
          std::cout<<"i will refuse to delete this object: " << o << "\n";
          std::cout<<"not my responsibility." <<std::endl;
      };
      std::shared_ptr<int> sptr(&x,ignore);
      
      
      //statically via unique_ptr:
      //  actually, the unique_ptr is as data structure not more than a regular pointer.
      //  but a pointer with special copy-constructor and destructor,
      //  which will most likely be inlined.
      //  there is no space to store a reference to a Deleter dynamically.
      struct IgnorantDeleter{
          void operator()(int* o){
              std::cout<<"who ate my cake? " << o << "\n";
              std::cout<<"but i baked it." <<std::endl;
          }
      };
      std::unique_ptr<int,IgnorantDeleter> uptr(&x);
      

      【讨论】:

        【解决方案4】:

        您不应创建指向非动态分配对象的智能指针。否则智能指针可能会尝试删除分配的内存,这反过来会导致错误。

        【讨论】: