【发布时间】:2014-05-12 22:05:11
【问题描述】:
我有一个类,它有一个指向动态分配实例 (wallGameObjects) 的指针的 2D 向量,我想在调用析构函数时将其删除,但在析构函数执行时该向量已被销毁。
析构函数调用removeMaze():
MazeSceneBuilder::~MazeSceneBuilder()
{
removeMaze();
mSceneManager->destroySceneNode(mazeNode);
}
而且对象的成员变量已经没有了:
void MazeSceneBuilder::removeMaze()
{
// Remove walls
for (unsigned int x = 0; x < mazeWidth; x++)
{
for (unsigned int z = 0; z < mazeWidth; z++)
{
if (wallGameObjects[x][z] != nullptr)
{
mGameObjectManager->removeGameObject(wallGameObjects[x][z]);
}
}
}
// remove ground
mGameObjectManager->removeGameObject(groundGameObject);
// Destroy collision shapes
destroyCollisionShapes();
}
“mGameObjectManager->removeGameObject(groundGameObject);”行上的断点显示这个:
this 0x00000000 <NULL> MazeSceneBuilder *
这对我来说没有意义。我试图在对象被销毁之前调用“removeMaze()”,它工作得很好。 对象的成员是否应该在析构函数执行之前消失?
编辑:
根据要求,这是 MultiplayerMaze 的析构函数:
MultiplayerMaze::~MultiplayerMaze()
{
destroyPhysicsWorld();
}
摧毁物理世界:
void MultiplayerMaze::destroyPhysicsWorld()
{
delete dynamicsWorld;
delete solver;
delete collisionConfiguration;
delete dispatcher;
delete broadphase;
}
编辑 2:
MultiplayerMaze 类定义:
class MultiplayerMaze : public BaseApplication
{
public:
MultiplayerMaze();
virtual ~MultiplayerMaze();
protected:
virtual void createScene();
virtual bool frameRenderingQueued(const Ogre::FrameEvent& evt);
virtual bool configure();
virtual void createPhysicsWorld();
virtual void destroyPhysicsWorld();
// Physics members
btBroadphaseInterface* broadphase;
btDefaultCollisionConfiguration* collisionConfiguration;
btCollisionDispatcher* dispatcher;
btSequentialImpulseConstraintSolver* solver;
btDiscreteDynamicsWorld* dynamicsWorld;
GameObjectManager gameObjectManager;
MazeSceneBuilder mazeSceneBuilder;
MazeGenerator mazeGenerator;
};
MazeSceneBuilder 类定义:
class MazeSceneBuilder
{
protected:
std::vector<std::vector<bool>> mMaze;
unsigned int mazeWidth, mazeHeight;
float mMazeScale;
GameObjectManager* mGameObjectManager;
Ogre::SceneManager* mSceneManager;
Ogre::String mWallEntity;
Ogre::String mGroundMaterial;
Ogre::Entity* mGround;
Ogre::SceneNode* mazeNode;
btCollisionShape* wallCollisionShape;
btCollisionShape* collisionPlanes[5];
GameObject* groundGameObject;
std::vector<std::vector<GameObject*>> wallGameObjects;
void setupGround(); // Creates a plane entity using the ground materiala and the maze size.
void createCollisionShapes(); // Create collision shapes for the wall, ground, and bounding planes.
void destroyCollisionShapes();
void DestroyAllAttachedMovableObjects(Ogre::SceneNode* sceneNode);
public:
MazeSceneBuilder();
MazeSceneBuilder(GameObjectManager* gameObjectManager);
~MazeSceneBuilder();
void setGameObjectManager(GameObjectManager* gameObjectManager);
bool setMaze(std::vector<std::vector<bool>> maze); // Returns false if the provided maze was invalid.
void setMazeScale(float scale);
void setWallEntity(Ogre::String entityName); // Must be a square cuboid of 1x2x1
void setGroundMaterial(Ogre::String materialName); // Should be a tiled square texture.
void buildMaze();
void updateMaze(const std::vector<std::vector<bool>>& maze);
void removeMaze();
};
【问题讨论】:
-
你能看一下调用堆栈并检查你的析构函数在哪里被调用,如果它没有在你调用构造函数的那一行之后被自动调用?这 可以 为 nullptr,但前提是您手动调用构造函数在一个为 nullptr 的指针上。
-
您可以在 a) C++ 语言实现缺陷、b) 宇宙射线粒子翻转 RAM 位、c) 您的代码破坏堆之间做出选择。 a 和 b 更容易消除。
-
@Muepe 在析构函数之后调用它: Multiplayer Maze.exe!MazeSceneBuilder::removeMaze() Line 192 C++ Multiplayer Maze.exe!MazeSceneBuilder::~MazeSceneBuilder() Line 30 C++ 我不知道从其他任何地方调用它,为什么?
-
@yoni0505 不是从哪里调用 removeMaze 而是从哪里调用你的构造函数?您是手动删除您的对象,还是从超出范围的对象中自动析构函数?
-
@yoni0505 - 但您没有禁用复制。因此,如果复制了 MazeSceneBuilder 对象,您的程序将表现出未定义的行为。但说真的,我们需要有一个正在运行的程序来查看您是如何使用这些类的。所有这些指针和成员都有太多可能出错的地方。也许重新编写代码以使用智能指针而不是赤裸裸的原始指针会很有帮助,如果不能消除您现在遇到的问题。
标签: c++ destructor