正如 Xeo 在他的回答中所说,解决方案通常是使用x.get()
.
有一个在需要访问时FILE
使用的示例:x.get()
void file_deleter(FILE *f)
{
fclose(f);
}
[...]
{
std::unique_ptr<FILE, decltype(&file_deleter)>
f(fopen("/tmp/test.tmp", "rw"), &file_deleter);
// read/write use f.get() as in:
fread(buf, 1, sizeof(buf), f.get());
fwrite(buf, 1, sizeof(buf), f.get());
// fclose() gets called in the deleter, no need to do anything
}
但是,在您的情况下,您需要使用x.release()
.
A a;
{
unique_ptr<X> x(new X());
a.va_x.push_back(&(*x)); // this is wrong
}
// here a[0] is a dangling pointer
将&(*x)
获取原始指针并在a
向量中进行复制。但是,在unique_ptr<>
超出范围时,该指针将被删除。所以在 之后}
,向量中的指针a
不再好(尽管它可能会工作一段时间。)
传输裸指针的正确方法是使用如下release()
函数:
a.va_x.push_back(x.release()); // this works
在那一行之后,指针仅在a
向量中。它是从唯一指针中释放出来的,其想法是调用者现在负责管理该资源。
重要提示:可能push_back()
会抛出 ( bad_alloc
),如果发生这种情况,资源将丢失。为避免该问题(如果您的软件捕获bad_alloc
并继续运行),您需要首先在向量中保留空间,如下所示:
a.va_x.reserve(a.va_x.size() + 1); // malloc() happens here
a.va_x.push_back(x.release()); // no `bad_alloc` possible here
这样,bad_alloc
当资源仍然附加到时,就会在该语句上发生,并且unique_ptr
在发生异常时不会泄漏它。
综上所述,您可能需要一个shared_ptr
代替。这些可以毫无困难地复制。Aunique_ptr
更多的是用于分配一次资源,然后忘记一个函数返回或删除一个对象。当涉及(许多)副本时, ashared_ptr
更有意义。
class X
{
typedef std::shared_ptr<X> pointer_t;
[...]
}
class A
{
std::vector<X::pointer_t> va_x;
}
X::pointer_t x(new X());
A a;
a.va_x.push_back(x); // much cleaner and the pointer is still managed