将现有值分配给smart-ptrs?

时间:2013-11-25 14:30:45

标签: c++ std shared-ptr tr1

我只是在学习智能指针,而且我无法将变量的预先存在的位置分配给标准库的共享指针。

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

int* ptr;
ptr = &x;

我尝试使用共享指针和

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

所以我完全迷失了如何去做。

4 个答案:

答案 0 :(得分:20)

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

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

答案 1 :(得分:3)

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

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

它的作用基本上保证当有人指向它管理的动态分配的内存时,那么这个内存将可用,并且一旦最后一个(智能)指向这个内存的指针超出范围,那么{{1调用。

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

答案 2 :(得分:1)

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

Deleter是一个简单的函数(默认为通常的operator delete),它必须通过模板参数(参见unique_ptr)静态地或通过构造函数参数动态地绑定到智能指针(参见{{3 }})。

// 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);

答案 3 :(得分:0)

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