C++ 实例化奇点

C++ 实例化奇点,c++,C++,我有一个问题,指针向量似乎没有以我预期的多态方式运行。奇怪的是,它对它指向的每一个其他对象都有效 shotgunNodes和rifleNodes都包含两个整数,它们表示一个级别中放置我生成的拾取的适当位置 pickups是kpointer(父类)的向量,ShotgunPU和RiflePU是派生类。我将在下面发布标题和源代码 奇怪的问题是,如果我打破代码,一次一个循环,一切似乎都很顺利。第一个枪指针被设置为指向步枪物体。好的然后,下一个枪指针被设置为指向下一个步枪对象,由于某种奇怪的原因,向量中的

我有一个问题,指针向量似乎没有以我预期的多态方式运行。奇怪的是,它对它指向的每一个其他对象都有效

shotgunNodes
rifleNodes
都包含两个整数,它们表示一个级别中放置我生成的拾取的适当位置

pickups
是kpointer(父类)的向量,
ShotgunPU
RiflePU
是派生类。我将在下面发布标题和源代码

奇怪的问题是,如果我打破代码,一次一个循环,一切似乎都很顺利。第一个枪指针被设置为指向步枪物体。好的然后,下一个枪指针被设置为指向下一个步枪对象,由于某种奇怪的原因,向量中的上一个指针(应该指向第一支步枪)被切断,现在只指向步枪对象的枪部分,因此我失去了它的所有派生功能

循环结束时,我有一个枪向量,指向枪-步枪-霰弹枪,应该是步枪-霰弹枪

int j = 0;

for (vec_i_sz i = 0; i < rifleNodes.size(); i++, j++)
{
    riflePickups.push_back(RiflePU(agents, mesh));
    riflePickups[i].Position(nodes[rifleNodes[i]].Position());

    pickups.push_back(&riflePickups[i]);//point the pickup pointer to the rifle pickup
    pickups[j]->Index(j);
    pickups[j]->NodeIndex(rifleNodes[i]);
}

for (vec_i_sz i = 0; i < shotgunNodes.size(); i++, j++)
{
    shotgunPickups.push_back(ShotgunPU(agents, mesh));
    shotgunPickups[i].Position(nodes[shotgunNodes[i]].Position());

    pickups.push_back(&shotgunPickups[i]);
    pickups[j]->Index(j);
    pickups[j]->NodeIndex(shotgunNodes[i]);
}
intj=0;
对于(vec_i_sz i=0;i索引(j);
拾音器[j]->NodeIndex(rifleNodes[i]);
}
对于(vec_i_sz i=0;i索引(j);
拾音器[j]->NodeIndex(shotgunNodes[i]);
}
可能还值得注意的是,这段代码(显然是翻译版本,但结构相同)在程序的C#版本中工作。所以我怀疑这是代码的结构。指针的工作方式有什么我不知道的吗

这是在使用向量的标头中声明向量的方式:

std::vector<Pickup*> pickups;
std::vector<RiflePU> riflePickups;
std::vector<ShotgunPU> shotgunPickups;
std::向量拾取;
std::向量riflePickups;
std::矢量枪检具;
我在写这篇文章时注意到,在循环运行之前(在构造函数的主体中),它们实际上并没有在初始化器列表中初始化,但这不应该是正常的,因为它们是类类型吗

如果他们在名单上被草签了,这仍然在发生

pickups(std::vector<Pickup*>()),
riflePickups(std::vector<RiflePU>()),
shotgunPickups(std::vector<ShotgunPU>())
拾取(std::vector()), riflePickups(std::vector()), 霰弹枪拾音器(std::vector())
将项添加到向量时,
向后推
会使容器中的所有指针在需要调整其基础缓冲区大小时失效。每次发生这种情况时,您已经存储在
pick\u ups
中的指针都会变成垃圾

1) 您可以预先为
riflePickups
shotgunPickups
中的所有项目保留
内存。这将确保在添加许多项时不会调整这些向量的大小,并且项的地址将保持不变

2) 在两个向量中创建所有项后,可以将指针存储在拾取中,而不是当这些向量尚未达到其最终大小时

3) 您可以在向量上使用
std::list
用于
riflePickups
shotgunPickups
。在列表中,指向项的指针只有在所述项被删除时才会失效


最终,你真的需要这些吗?也许您可以只在一个向量中存储(最好是智能的)指向动态分配对象的指针。

“访问者”已经解释了发生了什么,正如他所暗示的,我认为您的根本问题是,当您应该使用指向对象的指针时,您使用对象。请记住,C#(和Java)确实使用指向所有对象的指针,即使从语法上看不明显。因此,当这个C#代码:

也会编译成C++,如果你只删除KEWORD < St><新>强>,当执行时会发生什么,接近这个C++代码:

Person* daisy = new Person();
daisy->salary = 39000;
dosomethingwith(daisy);

程序员和C++程序员经常犯的错误就是把C++创建成具有<强> < <强> >的所有对象,但也许相反的情况也是如此。

发布问题的最小代码。如果你不能把范围缩小,为什么会有人费心阅读整件事呢?把长长的代码放在一边:到底是什么问题?请描述问题,以便任何人在阅读千字节文本之前理解。此外:您提供了枪支和子弹等的所有代码(这是次要的),但您遗漏了“皮卡”和“步枪皮卡”以及“猎枪皮卡”的声明。。。既然您访问/修改了这些容器,那么哪个更有趣呢?@LuchianGrigore不会介意吧?发布代码需要付出更多的努力。我认为这是相关的,但现在它不见了。这太棒了,我一点都不知道。有一件事,你能给我链接一些关于智能指针的信息吗?我在他们身上找不到任何好的资源。
Person* daisy = new Person();
daisy->salary = 39000;
dosomethingwith(daisy);