将现有值分配给智能ptr

Assigning existing values to smart-ptrs?

本文关键字:智能 ptr 分配      更新时间:2023-10-16

我只是在学习智能指针,在将变量的预先存在的位置分配给标准库的共享指针时遇到了问题。

例如,假设你有一个int x,你不知道它的值。对于普通指针,我只是做了

int* ptr;
ptr = &x;

我用共享指针和尝试了这两种方法

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

所以我很不知道该怎么做。

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

您通常会使用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更好,因为它能更好地利用内存,并提供更强的异常安全性。

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

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

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

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

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

一旦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);