将现有值分配给智能指针?

22

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

例如,假设有一个 int x 变量,你不知道它的值。对于普通指针,我只需要执行:

int* ptr;
ptr = &x;

我尝试过使用共享指针,以及...

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

所以我非常不清楚如何去做。


4
你极有可能不想将变量的地址传递给共享指针。共享指针的目的是管理动态分配的对象。 - john
4个回答

34

通常情况下,您不会使智能指针指向已存在的变量。智能指针管理动态分配对象的生命周期,在使用后删除它;如果将其指向未经动态分配的内容,则在尝试删除时会导致错误。

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


谢谢。当我的构造函数是私有的并且从类内部进行构造时,我不得不使用“new”方法。编译器不喜欢非公共构造函数,而我又不想将构造函数设为公共。 - GilesDMiddleton

5

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

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

它的作用基本上是保证只要有人指向它所管理的动态分配的内存,那么这个内存就会可用,并且只要指向该内存的最后一个(智能)指针超出其作用域,那么delete就会被调用。

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


2
一旦 shared_ptr 的引用计数器达到零,最后一个 shared_ptr 将删除该对象。使用智能指针,您可以指定将删除该对象的函数。
Deleter 是一个简单的函数(默认为常规 operator 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);

2

不应该创建指向非动态分配对象的智能指针。否则,智能指针可能尝试删除已分配的内存,从而导致错误。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接