在for循环中创建的C++多态指针指的是同一个东西,这是因为我没有使用智能指针吗?

C++ polymorphic pointers created in for loop refer to the same thing, is this because I'm not using smart pointers?

我的程序中有一个基础 class 和两个子class。 我是 c++ 的新手而且不 我有类似于以下循环的内容:

baseclass * arr[10];
for (i = 0; i < 10; i++) {
   if (some condition) {
    SubclassA subA;
    subA = SubclassA(stuff);
    arr[i] = &subA;
   }
   else if (some other condition) {
    SubclassB subA;
    subB = SubclassB(stuff);
    arr[i] = &subB;
   }
}

当我 运行 我的代码并首先创建一个 SubclassA 并将其地址分配给我的数组时。 但是我发现发生了以下情况:在上一步之后,当我稍后在循环中创建一个 SubclassB 时,SubclassB 出于某种原因正在同一内存位置创建我的 SubclassA 位于:它完全覆盖了我的第一个对象,我不明白为什么。

您需要使用指针并创建 new 个对象来添加到数组中,而不是使用本地对象。

baseclass * arr[10];
for (i = 0; i < 10; i++) {
   if (some condition) {
    arr[i] = new SubclassA(stuff);
   }
   else if (some other condition) {
    arr[i] = new SubclassB(stuff);
   }
}

别忘了你需要遍历数组并在完成后删除指针。

for (i = 0; i < 10; i++) {
   delete arr[i];
}

在 C++ 中 subA = SubclassA(stuff); 并不意味着分配和创建一个全新的对象,然后为其分配一个引用。 subA 是一个本地对象,一旦到达封闭的 } 就会消失。您不能将其地址存储到数组中。

您需要使用 new 实际分配新对象,最好使用智能指针来控制所有权和生命周期:

Typedef std::array<std::unique_ptr<baseclass>, 10> ArrType;
ArrType arr;
for (i = 0; i < 10; i++)
{
    if (some condition)
    {
        arr[i] = ArrType::value_type(new SubclassA(stuff));
    }
    else if (some other condition)
    {
        arr[i] = ArrType::value_type(new SubclassB(stuff));
    }
}

尝试在你的子类中使用 new

baseclass * arr[10];
    for (i = 0; i < 10; i++) {    
        if (some condition) {
        SubclassA subA =  new SubclassA(stuff);
        arr[i] = subA;    
        }    
        else if (some other condition) {
        SubclassB subB = new SubclassB(stuff);
        arr[i] = subB;    
        } 

}

您正在存储指向局部变量 subAsubB 的指针。当变量超出范围时,对象将被删除,指针将悬空。

要修复它,您必须使用动态内存分配。建议使用std::unique_ptr等智能指针管理动态分配的内存。

std::vector<std::unique_ptr<baseclass>> arr;

for (int i = 0; i < 10; i++) {
  if (some condition) {
    arr.push_back(std::make_unique<SubclassA>());
  } else if (some other condition) {
    arr.push_back(std::make_unique<SubclassB>());
  }
}