2010-10-01 6 views
15

J'ai des problèmes pour essayer d'utiliser la fonction ami de C++. J'ai ces interfaces:Classes d'amis dans différents espaces de noms. Est-ce possible

#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); 
     }; 

    }; 

}; 

et

#pragma once 
#include "GeometryManager.h" 

class CGeometryManager3D; 
namespace render{ 

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

}; 

Je ne sais pas ce qui se passe, mais beaucoup d'erreurs sont jetés par le compilateur (Visual C++ 2008). Il est possible de résoudre cela?

modifier: Le code ci-dessus est un code fictif pour montrer mon problème. Votre solution fonctionne bien pour ce code, mais quand je l'ai mis en pratique dans mon vrai code, ça n'a pas fonctionné. Le code réel est neearly le même:

#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_ 

et

#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_ 

Le compilateur retourne une erreur qui dit « CMesh3D » est pas membre de rendre. Encore une fois, toute aide est la bienvenue. :)

éditer 2: Je l'ai résolu en renvoyant la déclaration de chaque classe et son propre espace de noms dans les deux classes. Je pensais que cela devrait échouer par une déclaration circulaire, mais cela fonctionne finalement parfaitement.

Merci à tous pour votre aide.

+0

Le premier fichier s'appelle 'GeometryManager.h' et le second fichier' Mesh3D.h'? Si oui, vous avez un problème d'inclusion circulaire. –

+0

@James c'était ma pensée. –

+0

Non ... aucune inclusion circualar n'apparaît. Dans une inclusion B et B comprend A, vous résolvez l'inclusion circulaire en transmettant la déclaration de l'un des clases dans l'autre, comme je l'ai fait dans mon code. – Killrazor

Répondre

26

Voir si quelque chose comme ça fonctionne un peu mieux (pour l'instant, je les ai fusionnés en un seul fichier source).

#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

Actuellement en attente de nouveaux votes, mais qualifier la déclaration forward avec le bon confinement de l'espace de noms est certainement la bonne solution. –

+1

Probablement, les points-virgules après les blocs d'espace de noms ne sont pas requis. – Arun

+0

J'ai testé en renvoyant la déclaration de CGeometryManager en tant qu'outils :: sysInput :: CGeometryManager, mais cela n'a pas fonctionné. Maintenant ça marche!! – Killrazor

-3

Je suppose que vous devez supprimer le code suivant dans le second fichier:

#include "GeometryManager.h" 

class CGeometryManager3D; 

La première ligne provoque l'inclusion circulaire que les commentaires dans la question suggère;

La deuxième ligne déclare une classe totalement non pertinente telle qu'elle est dans l'espace de nom global;

+0

Non, cela ne fonctionne pas. – Killrazor

Questions connexes