Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 用std::shared\u ptr替换向量中的原始指针_C++_Pointers_Std_Shared Ptr_Stdvector - Fatal编程技术网

C++ 用std::shared\u ptr替换向量中的原始指针

C++ 用std::shared\u ptr替换向量中的原始指针,c++,pointers,std,shared-ptr,stdvector,C++,Pointers,Std,Shared Ptr,Stdvector,我的结构如下: typedef Memory_managed_data_structure T_MYDATA; std::vector<T_MYDATA *> object_container; std::vector<T_MYDATA *> multiple_selection; T_MYDATA * simple_selection; typedef Memory\u managed\u data\u structure T\u MYDATA; std::向量对象_

我的结构如下:

typedef Memory_managed_data_structure T_MYDATA;
std::vector<T_MYDATA *> object_container;
std::vector<T_MYDATA *> multiple_selection;
T_MYDATA * simple_selection;
typedef Memory\u managed\u data\u structure T\u MYDATA;
std::向量对象_容器;
std::向量多重选择;
T_MYDATA*简单的_选择;
编辑:这可能非常重要:内存管理的数据结构包含一个指向其他数据的原始指针

它的目标是非常简单地表示内存管理对象的原始容器(object_container),然后是“multiple_selection”数组(用于选择范围内的多个对象并使用它们执行各种操作)和“simple_selection”指针(用于对单个对象执行这些操作)

所有对象的生存期都由对象容器管理,而多个对象选择和简单对象选择仅指向其中一些对象。可以根据需要取消多个_选择和简单_选择,并且只能删除对象_容器对象

该系统工作正常,但我现在正试图进入共享PTR,并希望将结构更改为:

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;
typedef Memory\u managed\u data\u structure T\u MYDATA;
std::向量对象_容器;
std::向量多重选择;
std::共享\u ptr简单\u选择;
同样,对象容器将是“所有者”,其余的将只是指向它们。我的问题是,这项计划会对申请产生影响吗?。在滚雪球般地进行这些改变之前,我应该知道些什么吗?。这里的指针不是共享的吗

我可以在某种程度上保证,如果对象不在object\u容器中,则在多个\u选择或简单的\u选择中不会存在任何对象。当然,在多个_选择或简单_选择中不会调用delete

谢谢你抽出时间

编辑:忘了提一下,以前从未使用过这些自动指针,所以我可能对它们的用途感到非常困惑。任何提示和经验法则都将不胜感激

我可以在某种程度上保证,世界上不存在任何物体 多个\u选择或简单\u选择(如果不在 首先是对象容器

如果你有150%的把握,那么就不需要智能ptr了

我认为,在这种情况下,您可能需要它的原因是调试。 在您描述的情况下-多重选择和简单选择不是共享的\u ptr,而是弱的\u 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 owner\u vector;
std::向量弱_向量;
int*a=新的int(3);
所有者向量。推回(a);
弱向量。推回(a);
std::每个(
所有者_vector.begin(),
所有者_vector.end(),
[](int*ptr){
删除ptr;
}
);
std::每个(
弱_向量。begin(),
弱_向量.end(),
[](int*ptr){
*ptr=3;//oops…删除指针的用法
}
);
您可以使用智能指针捕捉它:

  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;
      }
  );
std::vector owner\u vector;
std::向量弱_向量;
{
自动a=std::使_共享();
所有者向量。推回(a);
弱向量。推回(a);
}
std::每个(
所有者_vector.begin(),
所有者_vector.end(),
[](标准::共享ptr&ptr){
ptr.reset();//内存删除
}
);
std::每个(
弱_向量。begin(),
弱_向量.end(),
[](标准:弱ptr和ptr){
断言(!ptr.expired());//保证处于活动状态
自动共享_ptr=ptr.lock();
*共享_ptr=3;
}
);

在上一个示例中,断言失败,但不是未定义/分段错误。在非调试情况下,您可以禁用共享开销,您可以说,对象容器将是相关对象的“所有者”。在这种情况下,如果您有一个明确的拥有关系,那么使用std::shared_ptr并不理想。相反,坚持你所拥有的

但是,如果无法保证指针在删除之前已从多个\u选择和/或简单\u选择中删除,则必须执行操作。一个可能的操作是,使用共享的ptr。在这种情况下,一个对象仍然可以继续存在于其中一个选择中,即使它已从对象容器中删除(通过共享的\u ptr::reset或仅分配空值)


另一种选择是确保彻底删除对象:如果要删除某个对象,请从选择和对象容器中删除对该对象的所有引用,然后将其删除。如果严格遵循此方案,则不需要共享的ptr开销。

如果对象容器是所有者,则
std::shared_ptr
不是正确的智能指针。刚刚意识到并编辑了问题。。。关于我可以为业主和从中借钱的人使用哪种结构的任何提示?
std::unique\u ptr
用于唯一所有权。这意味着当拥有的容器超出范围时,所有托管指针都将被删除。如果容器要拥有指针,那么就由您来确保它们在容器超出范围或删除其元素后不会被使用。我可以在真正的容器中使用这些指针。。。那些向它借钱的人呢?。有没有什么东西可以避开原始指针?。非常感谢您的时间Juanchpoanza。对从object_容器借用的容器使用原始指针。只需确保这些容器不会比object_容器更长寿。谢谢Kai。我可以保证这里有一个明确的拥有关系,而且,代码的工作原理与您描述的一样:在原始向量中发生任何更改之前,彻底删除每个引用。问题是,我真的很想学习C++11做事的方法,我想知道是否有任何智能指针的组合可以模拟业主-借款人的关系。其他评论中给出了一些有用的提示,但欢迎选择其他任何提示作为正确答案。并不是说其余的都错了,而是因为我会按照它的建议去做