我有一个std::vector
和unique_ptr
s,我很高兴让他们管理这些对象的生命周期。
但是,为了方便起见,我需要存储指向这些对象的其他指针。我知道一旦unique_ptr
删除了一些东西,其他指针就会挂起。但我更关心的是unique_ptr
获取指针前后指针的有效性。
我并不总是在unique_ptr
本身中通过new
创建,例如,我可能会将new Something
作为函数参数传递,在这种情况下,unique_ptr
在该指针上使用move
,使其在函数内部。
但在我将其传递给一个函数之前,我也可能是new Something
,然后该函数为它分配了一个unique_ptr
。
一旦一个对象被分配给unique_ptr
,我就可以通过get()
获得指向它的指针。但是,如果原始指针是在分配给unique_ptr
之前创建的,那么我可以一直假设这个get()
指针指向与最初通过new
获得的指针相同的位置吗?
我的假设是肯定的,即使vector
调整大小并重新分配,unique_ptr
以及指向内存中对象的任何其他指针也保持不变。
是的,std::unique_ptr<T>
包含pointer to T
,并且在初始化和稍后使用get()
检索之间不会更改值
unique_ptr
的一个常见用途是分配一个动态分配的"子对象"的"父"对象所有权,类似于:
struct A
{
B b;
}
int main()
{
A a = ...;
B* p = &a.b;
}
CCD_ 23是CCD_。
将其与进行比较
struct A
{
unique_ptr<B> b = new B(...);
}
int main()
{
A a = ...;
B* p = a.b.get();
}
在上面的A
和(*b)
具有与第一示例类似的关系,除了这里B
对象被分配在堆上。在这两种情况下,A的析构函数都会破坏"子对象"。在某些情况下,这种"堆上"子对象结构可能更可取,例如,因为B
是多态基类型,或者使B
成为A
的可选/可为null的子对象。
与原始指针相比,使用unique_ptr
来管理这种所有权关系的优势在于,它将在As
析构函数中自动销毁它,并且它将自动移动构造并将其作为a.的一部分进行移动分配
通常,在这两种情况下,都必须小心,指向子对象的任何原始指针的生存期都包含在所属对象的生存期内。
是的,您是正确的,因为unique_ptr
没有复制对象;因此,它必须指向相同的地址。然而,一旦您给了一个指向unique_ptr
的指针来拥有它,就不应该再使用该原始指针了,因为unique_ptr
可能会被破坏并释放内存,并将原始指针变成一个悬空指针。也许shared_ptr
会更适合你的情况。