包含原始指针的对象的 C++ 智能指针

C++ smart pointers for objects containing raw pointers

我有一个 class 有一个元素,其中包含另一个对象的原始指针,如下所示。请注意,我从我的实际工作中简化的示例可能会起作用,但如果我在这里做,我试图得到概念上的错误,因为在完全相同的结构和场景中我遇到了分段错误。

    /*This doesn't have a raw pointer of another object*/
       class H1 {
         private:
          int x, y;
         public:
          constructors;
          copy_constructor;
        }
    /*This has a h1_ptr element which is a raw pointer of H1*/
       class G1 {
         private:
          int count;
          H1* h1_ptr;
         public:
          G1(int c, H1* lst){
           count = 0;
           h1_ptr = lst;
         }
         G1(const G1& g) {
           count = g.count;
           h1_ptr = g.h1_ptr;
         }
         G1& operator=(const G1& g)
         {
           count = g.count;
           h1_ptr = g.h1_ptr;
         }
        }
    /*The class that I create unique_ptr from*/
class H3 {
         private:
          H1 h1, h2;
          G1 g1;
         public:
          H3(H1 _h1, H1 _h2, G1 _g1){
             h1 = _h1; h2 = _h2; g1 = _g1;
          }
        }

我在一个函数中从 class H3 创建了一个 unique_ptr 并且 return 它到另一个函数:

unique_ptr<H3> create_ptr(){
      H1 h1(5, 10);
      H1 h2(50, 100);

      H1* h1_lst = new H1[20];
      H1 ls;
      for (int i=0;i<20;i++)
      {
        H1 ls(i, i*2);
        h1_lst[i] = ls;
      } 
      G1 g1(200, h1_lst);
      unique_ptr<H3> p_h3(new H3(h1, h2, g1));
      return p_h3;
    }
 int main(){
   unique_ptr<H3> p_h3 = create_ptr();
   H3* h_3 = p_h3.get();//to get the raw pointer
   G1 g1(h_3->g1);//corrected
   H1* h1_lst = g1.h1_ptr;
   for (int i=0;i< 5; i++){
     //I just want 5 of them even if there is more
     H1 ls = h1_lst[i];
     cout << ls.x << ":" << ls.y << endl;
   }
   return 0;
 }

这只会写入 1 或 2 行,然后它会因分段错误而崩溃。如果我没有 return 唯一指针,而是获取原始指针并将结果写入 create_ptr 函数,它会工作得很好。

您不能从另一个唯一指针复制分配 std::unique_ptr。它不是 CopyConstructible 或 CopyAssignable。

但是,您可以使用 std::move 转让所有权:

std::unique_ptr iptr1{new int{1}};
std::unique_ptr iptr2 = std::move(iptr1); // iptr1 now null 

如果您希望指针拥有多个所有者,请改用 std::shared_ptr

在 cppreference 页面上阅读更多相关信息 std::unique_ptr

问题出在外部 class 的析构函数中,例如(本例中的 G1)试图删除原始指针对象。当我删除那些删除进程时,它工作正常,但我认为这仍然是一个坏主意。