Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Friend classes across different namespaces. Is that possible

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). Is it 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.

like image 708
Killrazor Avatar asked Oct 01 '10 23:10

Killrazor


People also ask

Can a function be friends with multiple classes?

A friend function can be friendly to 2 or more classes. The friend function does not belong to any class, so it can be used to access private data of two or more classes as in the following example. The friend functions can serve, for example, to conduct operations between two different classes.

Can two classes be friends in C++?

Two classes can friend each other; so that they can freely access the private and protected members of the other (I believe the answer is yes, and ofcourse I can simply try it out!). Any detailed references or other question links with answers are also very welcome.

Can a namespace have more than one namespace grouping?

You can have the same name defined in two different namespaces, but if that is true, then you can only use one of those namespaces at a time.

Are Friend classes inherited?

The privileges of friendship aren't inherited. Derived classes of a friend aren't necessarily friends.


1 Answers

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);         };      };     } 
like image 131
Jerry Coffin Avatar answered Sep 20 '22 10:09

Jerry Coffin