我不明白多线程游戏中的对象不匹配
I don't understand the object mismatch in a multithreading game
我正在开发一个多线程游戏。 它有3个类:
-
Carte
,一张由几个Case
组成的地图 -
Batiment
,一艘船,船只互相争斗。 -
Case
是地图的基本单元格,可以与Batiment
链接。
每个线程控制一个Batiment对象,一切似乎都很好,但是当我尝试输出游戏,显示代表地图中Batiment
的不同线程的ID号时,它不起作用。 它不会打印每个线程,而是只打印我在main.cpp
中创建的最后Batiment
。
我在上面停滞了 3 天...
这是我的文件:
主.cpp:
std::vector<Batiment> batiments;
for(int i = 0; i < nbrBatiments; i++){ //Ajout des Batiments sur le vecteur
//Batiment temp = new Batiment(&carte, i);
Batiment temp(&carte, i);
batiments.push_back(temp);
}
for(int i = 0; i < nbrBatiments; i++){
if ((rc = pthread_create(&thread[i], NULL, Batiment::launcher, (void *)&batiments[i]))) {
fprintf(stderr, "error: pthread_create, rc: %dn", rc); return EXIT_FAILURE;
}
}
Batiment.cpp:启动器函数,我用它来将对象传递给线程:
void *Batiment::launcher(void *context)
{
return static_cast<Batiment*>(context)->jouer();
}
Batiment.h:这里是班级的成员
Carte *carteInside;
static void *launcher(void *context);
int id;
void *jouer();
Case.h:这里是类的成员,它链接到一个 Batiment 对象:
Batiment *batiment;
我的Batiment::jouer()
方法只是一种移动地图中当前对象并拍摄另一个对象的方法......当我"cout"调用jouer()
对象的当前 id 时,所描述的问题发生在哪里
菜单.cpp:
for(int i = 0; i<this->x; i++){
for(int j = 0; j<this->y; j++){
if(this->carte[i][j].libre == false){
printf("%d", this->carte[i][j].batiment->id);
}
}
}
Carte.h:班级成员
std::vector< std::vector<Case> > carte;
编辑:Batiment
的构造函数:
Batiment::Batiment(Carte *carte, int i) {
this->carteInside = carte;
do{
this->x = doRand(0, carte->x);
this->y = doRand(0, carte->y);
}
while(!carteInside->carte[x][y].libre);
this->id = i;
this->orientation = doRand(0, 3);
this->longueur = doRand(2, 4);
this->vie = 2*(this->longueur)*(this->longueur);
carte->carte[this->x][this->y].libre = false;
carte->carte[this->x][this->y].batiment = this;
}
问题是你通过 Batiment
的构造函数填充Carte
,但使用一个被销毁的临时对象使指针无效:
为什么?
在此语句中,您将创建一个临时Batiment
:
Batiment temp(&carte, i);
您的构造函数显然会在 Carte::carte[][]
中插入指向新创建的对象的指针。
不幸的是,您在 for 循环的块中定义了这个临时:
for(int i = 0; i < nbrBatiments; i++){ //Ajout des Batiments sur le vecteur
Batiment temp(&carte, i); // <=== L'instance n'existe que le temps d'une itération !!
...
}
因此,这个临时在这个循环的每次迭代中都会被创建和销毁。因此,一旦您离开循环,您的指针就无效。
当你稍后提到它时,它是未定义的行为。它找到任何有意义的价值只是运气。
顺便说一下,当您在向量中回推 temp 时,将创建对象的副本(相同的值,但仍然是另一个地址)。
怎么解决?
好吧,保持您初始设计的想法,有几种解决方案。
最简单的方法是在免费商店中创建您的Batiment:
Batiment *temp = new Batiment (&carte, i);
唯一的一点是,有一天需要在某处删除该对象。 因此,要么在 Carte 的析构函数中处理此问题,要么更改 vecotr 以保留指针,以便以后可以删除所有这些对象。
更好的方法是使用shared_ptr
,它们自己负责记忆管理。
- 为什么模板类中的对象不能返回值
- Qt SQLite没有查询或参数计数不匹配
- 模板参数推导失败,函数参数/参数不匹配
- 在使用累加时,C++中的运算符+不匹配
- C++ 与操作员不匹配<<
- 在 Arduino 上使用 sscanf 会导致与 const char * 不匹配,并且返回值始终相同,尽管输入值不同
- std::使用内部对象移动 - 与调用不匹配
- 对std::函数对象的调用不匹配,该对象是指向成员函数的指针
- 与操作数<传递对象不匹配
- 检测到来自同一 Visual Studio 2015 项目的源文件的对象文件的'RuntimeLibrary'不匹配
- 声明后初始化对象时"调用不匹配"
- 运行时库不匹配,尽管将正确的标志传递给所有对象?
- 我不明白多线程游戏中的对象不匹配
- 为什么函数中的对象输入不匹配但仍然有效
- 错误:调用对象不匹配
- 包含派生对象的QPointer和基类不匹配
- 在单独的文件夹中编译对象,隐式规则不匹配
- C++与自定义对象数组中的'operator='不匹配
- 从类返回模板化对象,模板类型不匹配
- C++,具有对象列表的对象:与"运算符=="不匹配