【问题标题】:Friend classes across different namespaces. Is that possible跨不同命名空间的友元类。那可能吗
【发布时间】:2011-04-20 02:42:14
【问题描述】:

我在尝试使用 C++ 的朋友功能时遇到问题。我有这些接口:

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

    };

};

#pragma once
#include "GeometryManager.h"

class CGeometryManager3D;
namespace render{

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

};

我不知道发生了什么,但是编译器会抛出很多错误(Visual C++ 2008)。 有没有可能解决这个问题?

编辑: 上面的代码是一个模拟代码来显示我的问题。您的解决方案适用于此代码,但是当我在我的真实代码中实施时,它不起作用。真正的代码几乎是一样的:

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

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

编译器返回一个错误,指出“CMesh3D”不是渲染的成员。 同样,欢迎任何帮助。 :)

编辑 2: 我已经通过在两个类中转发每个类的声明及其自己的命名空间来解决它。我认为这应该通过循环声明失败,但它最终完美地工作。

感谢大家的帮助。

【问题讨论】:

  • 第一个文件是GeometryManager.h,第二个文件是Mesh3D.h吗?如果是这样,您就有了循环包含问题。
  • 不...没有出现圆形夹杂物。在 a 包含 B 和 B 包含 A 中,您可以通过将其中一个类的声明转发到另一个类来解决循环包含,就像我在代码中所做的那样。

标签: c++ namespaces friend


【解决方案1】:

我猜你需要删除第二个文件中的以下代码:

#include "GeometryManager.h"

class CGeometryManager3D;

正如问题中的 cmets 所暗示的那样,第一行导致循环包含;

第二行声明了一个完全不相关的类,因为它在全局命名空间中;

【讨论】:

    【解决方案2】:

    看看这样的东西是否更好用(目前,我已将它们合并到一个源文件中)。

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

    【讨论】:

    • 目前正在等待新的投票,但使用正确的命名空间包含限定前向声明绝对是正确的解决方案。
    • 可能命名空间块后面的分号是不需要的。
    • 我已经通过将 CGeometryManager 的声明转发为 tools::sysInput::CGeometryManager 进行了测试,但它没有用。现在可以了!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-02
    • 2017-05-03
    • 2013-04-17
    • 1970-01-01
    • 1970-01-01
    • 2012-06-11
    • 2012-06-11
    相关资源
    最近更新 更多