2010-10-01 26 views
15

Tengo problemas al intentar usar la función de amigo de C++. Tengo estas interfaces:Clases de amigos en diferentes espacios de nombres. Es posible

#pragma once 
#include "Mesh3D.h" 
#include <string> 
namespace tools{ 
    namespace sysInput{ 
     class CGeometryManager3D 
     { 
     public: 
      bool loadFromFile(render::CMesh3D& mesh, std::string filename); 
      CGeometryManager3D(void); 
      ~CGeometryManager3D(void); 
     }; 

    }; 

}; 

y

#pragma once 
#include "GeometryManager.h" 

class CGeometryManager3D; 
namespace render{ 

    class CMesh3D 
    { 
    public: 
     friend class tools::sysInput::CGeometryManager3D; 
     CMesh3D(void); 
     ~CMesh3D(void); 
    }; 

}; 

No sé lo que está pasando, pero una gran cantidad de errores se tiran por el compilador (Visual C++ 2008). Es posible resolver esto?

editar: El código anterior es un código falso para mostrar mi problema. Su solución funciona bien con este código, pero cuando puse en práctica mi código real no funcionó. El código real es neearly la misma:

#ifndef _ZELESTE_IO_GEOMETRY_MANAGER_H_ 
#define _ZELESTE_IO_GEOMETRY_MANAGER_H_ 

#include "ResourceLocationManager.h" 
#include <string> 
#include "../../render/C3DMesh.h" 


namespace tools{ 
    namespace sysInput{ 
     class CGeometryManager 
     { 
     private: 
      CGeometryManager(void); 
      ~CGeometryManager(void); 
      static CGeometryManager* m_instance; 
     public: 
      static CGeometryManager* getInstance(); 
      bool load3DGeometryFromFile(render::C3DMesh* mesh, const std::string filename); 

     }; 
    }; 
}; 

#endif //_ZELESTE_IO_GEOMETRY_MANAGER_H_ 

y

#ifndef _C3D_MESH_H_ 
#define _C3D_MESH_H_ 

#include "Mesh.h" 
#include "../tools/io/GeometryManager.h" 
#include <string> 

namespace tools{ 
    namespace sysInput{ 
     class CGeometryManager; 
    } 
} 

namespace render{ 
    class C3DMesh 
     :public CMesh 
    { 
    public: 
     friend class tools::sysInput::CGeometryManager; 
     C3DMesh(void); 
     ~C3DMesh(void); 
    }; 

}; 
#endif // _C3D_MESH_H_ 

El compilador devuelve un error que dice "CMesh3D" no es un miembro de render. De nuevo, cualquier ayuda es bienvenida. :)

edit 2: Lo he resuelto enviando la declaración de cada clase y su propio espacio de nombres en ambas clases. Pensé que esto debería fallar por declaración circular, pero finalmente funciona perfectamente.

Gracias a todos por la ayuda.

+0

¿El primer archivo se llama 'GeometryManager.h' y el segundo archivo se llama' Mesh3D.h'? Si es así, tiene un problema de inclusión circular. –

+0

@James, esa fue mi idea. –

+0

No ... no aparece una inclusión circualar. En un include B y B incluye A, resuelve la inclusión circular al reenviar la declaración de una de las clases al otro, como hice en mi código. – Killrazor

Respuesta

26

Vea si algo como esto funciona un poco mejor (por el momento, los he fusionado en un único archivo fuente).

#include <string> 

namespace tools { 
namespace sysInput { 
class CGeometryManager3D; 
} 
} 

namespace render { 

    class CMesh3D 
    { 
    public: 
     friend class tools::sysInput::CGeometryManager3D; 
     CMesh3D(void); 
     ~CMesh3D(void); 
    }; 

}; 

namespace tools{ 
    namespace sysInput{ 
     class CGeometryManager3D 
     { 
     public: 
      bool loadFromFile(render::CMesh3D& mesh, std::string filename); 
      CGeometryManager3D(void); 
      ~CGeometryManager3D(void); 
     }; 

    }; 

}; 
+1

Actualmente, estamos a la espera de nuevos votos, pero la calificación de la declaración directa con la contención correcta del espacio de nombres es definitivamente la solución correcta. –

+1

Probablemente, los puntos y comas después de los bloques de espacio de nombres no son necesarios. – Arun

+0

He probado mediante la declaración de reenvío de CGeometryManager como herramientas :: sysInput :: CGeometryManager, pero no funcionó. ¡¡Ahora funciona!! – Killrazor

-3

Creo que se necesita quitar siguiente código en el segundo archivo:

#include "GeometryManager.h" 

class CGeometryManager3D; 

La primera línea hace que la inclusión circular, como los comentarios en la pregunta sugiere;

La segunda línea declara una clase totalmente irrelevante como lo es en el espacio de nombre global;

+0

No, no funciona. – Killrazor

Cuestiones relacionadas