views:

104

answers:

2

Hello all,

I'm having problems trying to use the friend feature of C++. I have these interfaces:

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

    };

};

and

#pragma once
#include "GeometryManager.h"

class CGeometryManager3D;
namespace render{

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

};

I don't know what is happening, but a lot of errors are thrown by the compiler (Visual C++ 2008). It is possible to solve this?

edit: Above code is a mock code to show my problem. Your solution works fine to this code but when I put in practice in my real code didn't work. The real code is neearly the same:

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

and

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

The compiler return an error that says "CMesh3D" is not a member of render. Again, any help is welcome. :)

edit 2: I've solved it by forwarding declaration of each class and its own namespace in both classes. I thought that this should fail by circular declaration, but it finally work perfectly.

Thanks to all for the help.

A: 

I guess you need to remove following code in the second file:

#include "GeometryManager.h"

class CGeometryManager3D;

The first line causes circular inclusion as the comments in the question suggests;

The second line declares a totally irrelevant class as it is in the global name space;

lz_prgmr
No, it don't work.
Killrazor
+4  A: 

See if something like this works a bit better (for the moment, I've merged them into a single source file).

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

    };

};
Jerry Coffin
Currently waiting for new votes, but qualifying the forward declaration with the right namespace containment is definitely the right solution.
Ben Voigt
Probably, the semicolons after the namespace blocks are not required.
ArunSaha
I've tested by forwarding declaration of CGeometryManager as tools::sysInput::CGeometryManager, but it didn't work. Now it works!!
Killrazor