【发布时间】:2018-08-10 21:44:26
【问题描述】:
我有一个基类的 unique_ptrs 全局向量,我将 unique_ptrs 附加到派生类:
std::vector<std::unique_ptr<Base>> global_vec;
template<typename T>
Base* create_object()
{
std::unique_ptr<T> uptr = std::make_unique<T>(/* ... */);
Base* last_ptr = uptr.get();
global_vec.emplace_back(std::move(uptr));
return last_ptr; /*this is a bit irrelevant, but is for the caller*/
}
现在,Base 本身有一个指向 Base 的原始指针的成员向量:
struct Base
{
...
std::vector<Base*> providers;
...
}
构成Base::providers的指针都是通过从global_vec调用unique_ptr::get()获得的:
void Base::subscribe_to(Base* src)
{
providers.push_back(src);
}
Base 有一个与这些订阅者一起工作的成员函数,并在工作之前检查 nullptr:
void Base::do_work()
{
...
for(Base* ptr : providers)
{
if(ptr != nullptr)
{
...
}
}
}
现在,在我的代码的其他地方,我可以擦除 global_vec 中的 unique_ptrs:
auto itr = std::find_if(global_vec.begin(), global_vec.end(), [&](std::unique_ptr<Base> const& n)
{ return n.get() == ptr_selected; }); //ptr_selected points to a widget selected by the user
global_vec.erase(itr);
然而,在擦除一个元素之后,Base::suscribers 仍然会持有一个指向对象的有效指针。也就是说,在 Base::do_work() 中迭代 Base::providers 时,没有 Base* 将等于 std::nullptr。
我希望从 global_vec 中删除 unique_ptr 会调用 Base::~Base(),从而将 Base::providers 中的指针呈现为 std::nullptr。 Base 的析构函数被调用,但指针是有效的(你甚至可以从它们中访问数据成员)。
Base 确实有一个虚拟析构函数。
为什么 Base::providers 中的指针仍然有效?
【问题讨论】:
-
get按值返回! -
销毁一个对象对指向该对象的指针没有影响,除非取消引用它们是未定义的。并且 undefined 有时似乎会起作用(无法确定指针是否有效)。
-
指针是一种方式。没有反向通道来更新指向同一对象的其他指针。实施这种渠道的簿记是不切实际的。
标签: c++ inheritance unique-ptr