我的C ++ directX 9应用程序中有一个克隆函数,它将对象的所有数据(如顶点和纹理)复制到一个新对象,而不是指向我创建的那个对象,如果我想要的话创建多个相同类型的对象。当我运行它时,一切似乎都很好,但是一旦我退出程序,它就崩溃了,我发现它与纹理有关(它没有正确删除。)。
好像我没有正确复制IDirect3DTexture9纹理。这是我得到的克隆功能:
OBJMesh* OBJMesh::Clone()
{
OBJMesh* newOBJMesh = new OBJMesh();
newOBJMesh->vertexCount = vertexCount;
newOBJMesh->indicesCount = indicesCount;
memcpy(&newOBJMesh->texture, &texture, sizeof(IDirect3DTexture9));
newOBJMesh->normalMapTexture = normalMapTexture;
newOBJMesh->vertices = new VERTEX[vertexCount];
memcpy(newOBJMesh->vertices, vertices, vertexCount * sizeof(VERTEX));
DirectX::device->CreateVertexBuffer(sizeof(VERTEX) * newOBJMesh->GetVertexCount(), 0, VERTEXFORMAT, D3DPOOL_MANAGED, &newOBJMesh->vertexBuffer, NULL);
VOID* vertexLocking;
newOBJMesh->vertexBuffer->Lock(0, 0, (void**)&vertexLocking, 0);
memcpy(vertexLocking, newOBJMesh->vertices, newOBJMesh->vertexCount * sizeof(VERTEX));
newOBJMesh->vertexBuffer->Unlock();
return newOBJMesh;
}
我使用memcpy(&newOBJMesh->texture, &texture, sizeof(IDirect3DTexture9));
作为纹理,这是复制它的正确方法吗?或者究竟是什么问题?
答案 0 :(得分:1)
首先,您应该重新考虑您的设计,因为您应该更喜欢将指针存储到已创建的对象,而不是深层复制周围的对象。
同样在C ++中,您正在寻找的功能通常通过复制构造函数实现,通常如下所示:
OBJMesh (const OBJMesh& other);
然后你仍然可以实现这样的克隆函数:
OBJMesh* OBJMesh::Clone() { return new OBJMesh(*this); }
然而,这并不是必要的,并且它更有可能导致内存泄漏,因为调用者负责删除对象,尽管他没有调用new
。
现在你的函数不起作用的原因是你正在复制类接口IDirect3DTexture9
的实例而不是实际的纹理资源。在这种情况下的结果很可能是未定义的,但你可能最终得到的是两个带有指向同一资源的对象,在你的对象被破坏时会被删除两次,而你现在无法处理的另一个纹理资源被删除。
至于解决方案,它取决于您尝试解决的问题,但您可能希望查看instancing。