我有以下结构:
typedef Memory_managed_data_structure T_MYDATA;
std::vector<T_MYDATA *> object_container;
std::vector<T_MYDATA *> multiple_selection;
T_MYDATA * simple_selection;
编辑:这可能非常重要:Memory_managed_data_structure包含一些指向其他数据的苦涩原始指针。
它旨在成为内存管理对象(object_container)的原始容器的非常简单的表示,然后是“multiple_selection”数组(用于选择范围内的许多对象并使用它们执行各种操作)和“simple_selection”指针(用于对单个对象执行这些操作)。
所有对象的生命周期由object_container管理,而multiple_selection和simple_selection只指向其中一些对象。 multiple_selection和simple_selection可以根据需要无效,只能删除object_container对象。
系统运行正常,但我现在正试图进入shared_ptrs并希望将结构更改为:
typedef Memory_managed_data_structure T_MYDATA;
std::vector<std::shared_ptr<T_MYDATA> > object_container;
std::vector<std::shared_ptr<T_MYDATA> > multiple_selection;
std::shared_ptr<T_MYDATA> simple_selection;
同样,对象容器将是“所有者”,其余的只是指向它们。我的问题是,这个计划会在应用程序中肆虐吗?在滚雪球进入这些变化之前,我应该知道些什么吗?这里不是shared_ptr适当的指针吗?。
我可以在某种程度上保证在multiple_selection或simple_selection中不存在任何对象,如果它首先不在object_container中。当然,在multiple_selection或simple_selection中都没有调用删除。
感谢您的时间。
编辑:忘记提及,之前从未使用过任何这些自动指针,所以我可能会对它们的用途感到非常困惑。任何提示和经验法则将不胜感激。
答案 0 :(得分:1)
我可以保证不存在任何对象 multiple_selection或simple_selection如果不在 object_container首先。
如果您确定150%,那么就不需要智能ptr。
我认为在这种情况下您可能需要它的原因是调试。 如果你描述 - multiple_selection和simple_selection不是 shared_ptr ,而是 weak_ptr 。
代码错误:
std::vector<int*> owner_vector;
std::vector<int*> weak_vector;
int* a = new int(3);
owner_vector.push_back(a);
weak_vector.push_back(a);
std::for_each(
owner_vector.begin(),
owner_vector.end(),
[](int* ptr) {
delete ptr;
}
);
std::for_each(
weak_vector.begin(),
weak_vector.end(),
[](int* ptr) {
*ptr = 3; // oops... usage of deleted pointer
}
);
你可以通过智能指针捕获它:
std::vector<std::shared_ptr<int>> owner_vector;
std::vector<std::weak_ptr<int>> weak_vector;
{
auto a = std::make_shared<int>();
owner_vector.push_back(a);
weak_vector.push_back(a);
}
std::for_each(
owner_vector.begin(),
owner_vector.end(),
[](std::shared_ptr<int>& ptr) {
ptr.reset(); // memory delete
}
);
std::for_each(
weak_vector.begin(),
weak_vector.end(),
[](std::weak_ptr<int>& ptr) {
assert(!ptr.expired()); // guarantee to be alive
auto shared_ptr = ptr.lock();
*shared_ptr = 3;
}
);
在上一个示例中,您将断言失败,但未定义/分段错误。在非调试的情况下,您可以禁用shared_ptr 开销。
答案 1 :(得分:1)
你说,对象容器将是所讨论对象的“所有者”。在这种情况下,你有一个明确的拥有关系,使用std :: shared_ptr并不理想。相反,坚持你所拥有的。
但是,如果你不能保证,在删除之前已经从multiple_selection和/或simple_selection中删除了一个指针,你必须采取行动。一个可能的操作可能是,您使用shared_ptr。在这种情况下,一个对象仍然可以继续存在于其中一个选择中,如果它被从object_container中删除(通过shared_ptr :: reset或只是赋值空值)。
另一种方法是确保彻底删除对象:如果要删除某些内容,请从选择和object_container中删除对它的所有引用,然后删除它。如果严格遵循此方案,则不需要shared_ptr的开销。