我正在使用SDL创建一个非常简单的Pong游戏。对于碰撞检测,我有一个名为DetectCollision的类,如下所示:
class DetectCollision {
public:
std::vector<Object*> objects;
int numOfObjects;
DetectCollision();
~DetectCollision();
void takeObjs(Object &);
void handleCollision();
};
所以会发生什么是takeObjs(Object&amp;)函数接受Object类的对象并将其存储在向量中。 takeObjs(Object&amp;)看起来像这样:
void DetectCollision::takeObjs(Object &obj1){
objects.push_back(&obj1);
}
到目前为止,一切都有效。我能够访问矢量“对象”来检测所有碰撞并且它工作正常,但问题出现在我试图删除矢量时。如果我没弄错的话,那就是指针的向量。所以我做的删除它是在类析构函数中:
DetectCollision::~DetectCollision(){
for (unsigned int i = 0; i < objects.size(); ++i){
delete objects[i];
}
objects.clear();
}
根据Code :: Blocks IDE使用GCC编译器,它在“删除对象[i];”上进行了段错误线。它还会对程序的另一部分进行分段,以尝试SDL_FreeSurface()类所持有的皮肤,但我认为我可以很容易地解决这个问题。这个向量是主要问题。如果您需要查看完整的源代码以帮助我学习如何解决问题,我可以提供。我非常感谢任何帮助。谢谢和DFTBA!
答案 0 :(得分:0)
一个潜在的问题是DetectCollision
违反了Rule of Three。如果复制了一个实例,该副本将获得相同Object
指针的向量,最终导致双delete
秒。
答案 1 :(得分:0)
您的应用段错误,因为调用析构函数时对象不再存在。
takeObjs
方法接收对象的引用,然后它在向量内存储指向该对象的指针。该对象在其他地方定义。当该对象超出范围时,它将自动销毁。
当你到达析构函数时,对象就会被破坏。应用程序段错误,因为你试图再次销毁它。
您应该阅读C ++中对象的范围(read the answer to this question),您还应该阅读Object destruction in C++。
编辑:添加简短示例以说明崩溃
#include <iostream>
#include <vector>
using namespace std;
class Object {
public:
int a;
int b;
Object(int a, int b)
{
this->a=a;
this->b=b;
}
};
class Test
{
std::vector<Object*> objects;
public:
Test(){}
void Add(Object &obj)
{
objects.push_back(&obj);
}
void Print()
{
for(unsigned int i=0;i<objects.size();i++)
{
cout<<objects[i]->a<<" "<<objects[i]->b<<endl;
}
}
~Test()
{
for (unsigned int i = 0; i < objects.size(); ++i){
delete objects[i];
}
objects.clear();
}
};
void AddNewObjects(Test &t)
{
Object x(1,2);
Object y(3,4);
t.Add(x);
t.Add(y);
// you can access your objects here
t.Print();
}
int _tmain(int argc, _TCHAR* argv[])
{
Test t;
AddNewObjects(t);
// but if you try to access the objects here, you get a crash
// because the objects were destroyed when exiting "AddNewObjects"
t.Print();
return 0;
// your destructor tries to access the objects here (in order to destroy them)
// and that's why it crashes
}
您可以使用以下解决方案来解决问题:
#include <iostream>
#include <vector>
using namespace std;
class Object {
public:
int a;
int b;
Object(int a, int b)
{
this->a=a;
this->b=b;
}
};
class Test
{
std::vector<Object*> objects;
public:
Test(){}
void Add(Object *pObj)
{
objects.push_back(pObj);
}
void Print()
{
for(unsigned int i=0;i<objects.size();i++)
{
cout<<objects[i]->a<<" "<<objects[i]->b<<endl;
}
}
~Test()
{
for (unsigned int i = 0; i < objects.size(); ++i){
delete objects[i];
}
objects.clear();
}
};
void AddNewObjects(Test &t)
{
Object* x = new Object(1,2);
Object* y = new Object(3,4);
t.Add(x);
t.Add(y);
// you can access your objects here
t.Print();
}
int _tmain(int argc, _TCHAR* argv[])
{
Test t;
AddNewObjects(t);
// you can also access the objects here
// because they are not destroyed anymore when exiting "AddNewObjects"
t.Print();
return 0;
}
答案 2 :(得分:0)
您可能有双重删除,因为传递给DetectCollision类的对象会在其他位置删除,可能是因为它们超出了范围。
你必须考虑谁将“拥有”这些物品。只有所有者才能删除它们。