C++ 对象的访问冲突
我有一个实体。h如下:C++ 对象的访问冲突,c++,arrays,oop,pointers,ogre,C++,Arrays,Oop,Pointers,Ogre,我有一个实体。h如下: PxGeometry geometry; if(mMesh == "sphere.mesh") { PxGeometry g = PxSphereGeometry(mDimensions.x / 2); // Because it's a radius geometry = g; } 使用名称空间physx class Entity { public: Entity(Ogre::Vector3 dims, Ogre::Vec
PxGeometry geometry;
if(mMesh == "sphere.mesh")
{
PxGeometry g = PxSphereGeometry(mDimensions.x / 2); // Because it's a radius
geometry = g;
}
使用名称空间physx
class Entity
{
public:
Entity(Ogre::Vector3 dims, Ogre::Vector3 pos, std::string mesh, std::string id);
virtual ~Entity(void);
virtual void update(Ogre::Real dt);
virtual void init(Ogre::SceneManager* sceneMgr, PxPhysics* physics, PxScene* scene, PxVec3 velocity=PxVec3(0, 0, 0));
protected:
Ogre::Entity* mOgreEntity = NULL;
Ogre::SceneNode* mOgreNode = NULL;
Ogre::Vector3 mPosition;
Ogre::Vector3 mDimensions;
std::string mMesh;
std::string mId;
PxRigidDynamic* mActor;
PxMaterial* mMaterial;
};
这是我的实体来源:
#include "Entity.h"
Entity::Entity(Ogre::Vector3 dims, Ogre::Vector3 pos, std::string mesh, std::string id)
{
mDimensions = dims;
mPosition = pos;
mMesh = mesh;
mId = id;
mActor = NULL;
mMaterial = NULL;
}
Entity::~Entity(void)
{
}
void Entity::update(Ogre::Real dt)
{
PxVec3 pos = mActor->getGlobalPose().p;
Ogre::Real r = 0;
mOgreNode->setPosition(Ogre::Vector3(pos.x + r, pos.y + r, pos.z + r));
}
void Entity::init(Ogre::SceneManager* sceneMgr, PxPhysics* physics, PxScene* scene, PxVec3 velocity)
{
// Create an Entity
mOgreEntity = sceneMgr->createEntity(mId, mMesh);
mOgreEntity->setCastShadows(true);
// Create a SceneNode and attach the Entity to it
mOgreNode = sceneMgr->getRootSceneNode()->createChildSceneNode(mId + "Node");
Ogre::AxisAlignedBox box = mOgreEntity->getBoundingBox();
Ogre::Vector3 realSizes = box.getSize();
mOgreNode->setPosition(mPosition);
mOgreNode->attachObject(mOgreEntity);
Ogre::Vector3 scaler = Ogre::Vector3(mDimensions.x / realSizes.x, mDimensions.y / realSizes.y, mDimensions.z / realSizes.z);
mOgreNode->scale(scaler);
mMaterial = physics->createMaterial(1.5f, 1.5f, 1.0f);
PxGeometry* geometry = NULL;
if(mMesh == "sphere.mesh")
{
PxGeometry g = PxSphereGeometry(mDimensions.x / 2); // Because it's a radius
geometry = &g;
} else {
// geometry = NULL;
}
PxTransform transform = PxTransform(PxVec3(mPosition.x, mPosition.y, mPosition.z));
mActor = PxCreateDynamic(*physics, transform, *geometry, *mMaterial, PxReal(.1));
// if(!mActor) {
// MessageBox( NULL, "no actor", "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
// return;
// }
mActor->setLinearVelocity(velocity);
// And add the actor to a scene:
scene->addActor(*mActor);
}
现在,如果我创建一个实体并初始化它,它就会工作。即使有第二个实体变量,它也可以工作。现在使用数组:
Entity *mEntities[20];
for(int i = 0 ; i < 20 ; i++ ){
ostringstream nameStream;
nameStream << "Sphere_" << i;
string name = nameStream.str();
Entity* sphere = new Entity(Ogre::Vector3(i*5, i*4.5, i*6), Ogre::Vector3(i*5, i*4.5, i*6), "sphere.mesh", name);
sphere->init(mSceneMgr, mPhysics, gScene, PxVec3(-10.0f, 0, 0));
mEntities[i] = sphere;
}
1)
查看“球体”+i
如果i
大于“球体”的长度,则将指针传递给某个随机内存。我假设您想创建一个字符串,结尾是I使用
sprintf
或std::string
2)如果将循环范围从20更改为3,那么它可能会工作。问题是您的姓名将是:
球体,球体,这里 因为通过执行
“Sphere\uu”+i
操作,您并没有将整数添加到字符串中这等于:
3)
此代码将生成您需要的字符串:
std::ostringstream newStringStream;
newStringStream << "Sphere_" << i;
std::string newString = newStringStream.str();
std::ostringstream newStringStream;
newStringStream还有一个问题:
PxGeometry* geometry = NULL;
if(mMesh == "sphere.mesh")
{
geometry = &PxSphereGeometry(mDimensions.x / 2); // Because it's a radius
}
这样做的问题是,您正在将临时值的地址指定给几何体。一旦那一行代码完成,临时代码就消失了
可能的解决方法是:
PxGeometry geometry;
if(mMesh == "sphere.mesh")
{
geometry = PxSphereGeometry(mDimensions.x / 2); // Because it's a radius
}
//...
mActor = PxCreateDynamic(*physics, transform, geometry, *mMaterial, PxReal(.1));
现在,geometry
不再是指针,您将几何体指定给返回的值(而不是返回值的地址)
我在这里阅读文档:
因此,PxSphereGeometry(x)
是一个构造函数调用。因此,您需要将返回值分配给PxSphereGeometry
,而不是PxSphereGeometry*
编辑:您最近的更改也没有达到预期效果:
if(mMesh == "sphere.mesh")
{
PxGeometry g = PxSphereGeometry(mDimensions.x / 2); // Because it's a radius
geometry = &g;
}
g
是if()。将此g
的地址分配给几何体
。然后,当该块退出时,g
消失,现在您有了指向不再存在的东西的几何体
您编辑的代码与我给出的答案之间的区别在于,我的答案将返回值指定给现有对象。所以我创建了一个返回值的副本。您在编辑的代码中所做的不是创建一个副本,而是指向一个本地对象,正如所解释的,在它离开作用域后,该对象将不存在
因此,如果要编写符合已编辑代码模式的代码,并使其有效,则更改如下所示:
PxGeometry geometry;
if(mMesh == "sphere.mesh")
{
PxGeometry g = PxSphereGeometry(mDimensions.x / 2); // Because it's a radius
geometry = g;
}
然而,这做了一些无关的工作。原来的答案就足够了。我尝试了另一种创建刚体的方法,它成功了
mActor = physics->createRigidDynamic(PxTransform(PxVec3(mPosition.x, mPosition.y, mPosition.z)));
PxShape* shape = mActor->createShape(PxSphereGeometry(mDimensions.x / 2), *mMaterial);
PxRigidBodyExt::updateMassAndInertia(*mActor, 0.4f);
我建议您在实体
的构造函数中将指针初始化为NULL。您的代码也绝对不会执行错误检查,以查看您正在调用的函数是否实际返回了良好的值。@PaulMcKenzie感谢您的建议,但我编辑了源代码,仍然收到以下错误:/。参见更新的postgeometry=&PxSphereGeometry(mDimensions.x/2)代码>请解释此行的作用。任何查看它的人都会认为您正在分配一个临时对象的地址,在该语句完成后,这绝对是不好的。呃,我正在创建一个几何变量,其中包含PxCreateDynamics要使用的几何体。错了吗?为什么?再次解释,但使用C++术语。您是否为geometry
分配临时文件的地址?如果是,那就不好了。感谢字符串,它没有解决访问抖动问题,但它解决了另一个问题,哪一行和哪一次迭代会崩溃?编辑:抱歉,没有正确阅读代码nvm.On-linemActor->setLinearVelocity(velocity)代码>第一次迭代谢谢,但是PxGeometry没有默认构造函数,这就是为什么使用指针来使用NULL@Vinz243-创建了一个对象,它是一个临时对象,您不能将指针指定给临时对象,并期望该指针在临时对象消失后指向任何有效的对象(这将在该语句结束时发生). 我不知道我能解释得多简单代码>至<代码>PxGeometry几何=PxSphereGeometry()代码>,它可以编译,但我仍然收到访问冲突错误。请将其更改为与我在答案中发布的完全相同。如果您将该语句放在if(mMesh…
块中,那么您刚才发布的内容也不正确。之所以不正确,是因为现在,geometry
是临时的,并且在if()时会消失
block完成。@Vinz243-刚刚看到了您的更改。根据我之前的评论,仍然是错误的。您需要学习对象生存期
和块范围
的基本知识。您在if()
块中局部声明了g
。该块一退出,它就会消失。
PxGeometry geometry;
if(mMesh == "sphere.mesh")
{
PxGeometry g = PxSphereGeometry(mDimensions.x / 2); // Because it's a radius
geometry = g;
}
mActor = physics->createRigidDynamic(PxTransform(PxVec3(mPosition.x, mPosition.y, mPosition.z)));
PxShape* shape = mActor->createShape(PxSphereGeometry(mDimensions.x / 2), *mMaterial);
PxRigidBodyExt::updateMassAndInertia(*mActor, 0.4f);