[c++]pointers

Started by
5 comments, last by Aardvajk 15 years, 5 months ago
Hy. I use directx for personal study... I have a mesh object pMesh of type ID3DXMesh* in the main class. I create an importer class that create inside a mesh with the function:
Quote: bool CImporter::CreateMesh(int nVertexes, int nIndexes) { HRESULT hr = D3DXCreateMeshFVF(12,8,D3DXMESH_MANAGED,Vertex::FVF,m_Device,&m_mesh); if(FAILED(hr)) { ::MessageBox(0, "Collada CreateMesh() - FAILED", 0, 0); return false; } return true; }
the class have a member var called m_mesh of type ID3DXMesh*. I create an istance of the importer class and pass the mesh class:
Quote: CImporter *cin= new CImporter(pMesh,Device,IMPORTER_COLLADA);
the mesh is loaded correctly in the importer class, but when i'm exit from the importer class the pMesh is null, but in the importer class the mesh have a fine value. Why? Thanks
Advertisement
My guess is your constructor for CImporter looks like this:

CImporter::CImporter(ID3DXMesh *mesh,IDirect3DDevice9 *Device,...etc);


What happens is that the function gets a copy of the mesh pointer, which it modifies. It doesn't modify the pointer you pass in. When the importer's constructor exits, the copy is destroyed.

You want to do this:

CImporter::CImporter(ID3DXMesh *&mesh,IDirect3DDevice9 *Device,...etc);


You are now passing the pointer by reference, so the original pointer will be modified, not a copy.

This is all assuming my initial guess is correct of course [smile].

[ASIDE] I don't really understand a couple of things:

a) why you need a class for Importer since it does all its work in the constructor - why can't you just have a function?

b) why do you need to create your CImporter with new? Why can't a normal instance be used?
Thanks , i think that your solution is good.
But for me there is another problem:
I have a member var called m_mesh and in the constructor i assig the parameter value of mesh:

Quote:
CImporter::CImporter(ID3DXMesh*& mesh,IDirect3DDevice9* Device ,int ImporterType)
{
m_mesh = mesh;
m_Device = Device;
switch(ImporterType)
{
case IMPORTER_COLLADA:
m_pApi = new CColladaReaderTriangles();
break;
}

}


but maybe that this is a copy?


m_mesh = mesh;


and if is a copy what type must be the m_mesh if i assign to the reference of mesh?
**ID3DXMesh?

and how i acces the public member of **ID3DXMesh?
i try
**m_mesh->
but don't work.


thanks.
It's a copy of the pointer, but it is pointing at the same thing.

Still I don't understand - why do you need to do this? From the code you have posted, it seems that all you do is new a class, do the work in the constructor then delete the class.

Why not just do it in a function and avoid all these ownership issues?
it would be easier to learn about pointer in console application. I've tried to do a simulation of the code.

#include <iostream>
typedef int ID3DXMesh ;//just a simulation
ID3DXMesh* m_Mesh = 0x00000000;
ID3DXMesh* mesh = 0x0041A164;
int _tmain(int argc, _TCHAR* argv[])
{
cout<<"here is the m_Mesh stays: "<<&m_Mesh<<" it points to:"<<m_Mesh<<endl;
cout<<"here is the mesh stays: "<<&mesh<<" it points to:"<<mesh<<endl;
cout<<endl<<endl;
return 0;
}

output:
here is the m_Mesh stays: 0041A160 it points to:00000000
here is the mesh stays: 0041A164 it points to:00000004

dont do this:
m_Mesh = &mesh // you will get a compiler error

first, try this:

m_Mesh = (ID3DXMesh*)&mesh
cout<<"then m_Mesh stays at: "<<&m_Mesh<<" and points to: "<<m_Mesh<<endl;
cout<<"mesh stays at: "<<&mesh<<" and it points to: "<<mesh<<endl;

output:
then m_Mesh stays at: 0041A160 and points to: 0041A164
mesh stays at: 0041A164 and it points to: 00000004

but m_Mesh points to mesh address.
it's not points to where mesh points to, you should replace the
previous code with:

m_Mesh = (ID3DXMesh*)&mesh
m_Mesh = mesh;

output:
then m_Mesh stays at: 0041A160 and points to: 00000004
mesh stays at: 0041A164 and it points to: 00000004

maybe it works, i dunno...
Another way: use IDirect3DMesh::CloneMesh (check for DirectX documentation)

I suppose that find the error:
The pointer mesh is not initializated,is NULL:
if i do this:
Quote:
hr = D3DXCreateMeshFVF(
12,
8,
D3DXMESH_MANAGED,
Vertex::FVF,
Device,
&Mesh);

if(FAILED(hr))
{
::MessageBox(0, "D3DXCreateMeshFVF() - FAILED", 0, 0);
return false;
}


CImporter cin = CImporter(Mesh,Device,IMPORTER_COLLADA);
cin.Init("c:\\giugio.dae");

the mesh is created(recreated) and loaded.
but i i do only this:

Quote:
CImporter cin = CImporter(Mesh,Device,IMPORTER_COLLADA);
cin.Init("c:\\giugio.dae");


i insert this in the constructor:

m_Mesh = (ID3DXMesh*)&mesh
m_Mesh = mesh;

if i check in debug:

output:
then m_Mesh stays at: 0041A160 and points to: 00000000
mesh stays at: 0041A164 and it points to: 00000000



the Mesh var is NULL and i can't create it in the class and out it.
is the possible problem?
and the ID3DXMesh is an abstract class and cant be inizialized!

thanks.
Huh?

m_Mesh = (ID3DXMesh*)&meshm_Mesh = mesh;


Assuming that m_Mesh and m_Mesh are both of type ID3DXMesh*, the first line is a horrible, horrible thing to do.

&mesh will return the address of the pointer, so is type ID3DXMesh** (pointer to pointer).

Doing a C-style cast (in this case, effectivly a reinterpret_cast) from ID3DXMesh** to ID3DXMesh* will cause undefined behaviour.

But then the next line overwrites m_Mesh with mesh anyway.

What is probably happening is this:

void f(ID3DXMesh *&mesh){    m_Mesh=mesh; // m_Mesh now points to same place as mesh    D3DXCreateMeshFVF(blah,blah,&m_Mesh);    // m_Mesh now points to different place than mesh          CreateMesh(100,100); // item mesh points to is unaffected}// function returns. What m_Mesh points at is unrelated to what mesh points at


If you really need to store the mesh in the class, you need to do this:

class Converter{private:    ID3DXMesh *&m_Mesh;public:   Converter(ID3DXMesh *&mesh) : m_Mesh(mesh) { }};


Since m_Mesh is a reference, it must be initialised in the constructor initialiser list. It is, however, now a true alias for mesh.

The design is silly though. Why pass the mesh into the Converter? Why not have Converter do all its work on its own mesh pointer then return the mesh pointer via a:

ID3DXMesh *Converter::GetMesh(){ return m_Mesh; }


method? You can then create your Converter, do all the work, then assign to your external mesh pointer from this method.

ID3DXMesh *mesh;void f(){    Converter c;    c.Init("model.x");    mesh=c.GetMesh();}


But then why can't Init's code be in the constructor?

void f(){    Converter c("model.x");    mesh=c.GetMesh();}


You don't really need to store the mesh inside the Converter class anyway.

class Converter{private:    void CreateMesh(const std::string &file,ID3DXMesh *&mesh){ /* do stuff */ }    void DecorateMesh(ID3DXMesh *mesh){ /* do stuff */ }public:    Converter(const std::string &file,ID3DXMesh *&mesh);};Converter::Converter(const std::string &file,ID3DXMesh *&mesh){    CreateMesh(file,mesh);    DecorateMesh(mesh);}ID3DXMesh *mesh;void f(){    Converter c("model.x",mesh);}

This topic is closed to new replies.

Advertisement