交友/使用不同命名空间中的类

Posted

技术标签:

【中文标题】交友/使用不同命名空间中的类【英文标题】:Friending/Using a class in a different namespace 【发布时间】:2014-01-29 13:48:17 【问题描述】:

如果G 类在命名空间GSpace 中,它需要与全局命名空间中的M 类成为朋友,你需要做什么?我认为这会起作用:

/////////////////////M.h//////////////////////
#include "GFile.h"

class M

   public:
      friend class GSpace::G; // doesn't work, throws error

在对 *** 进行了一番研究之后,我找到了这个答案https://***.com/a/3843743/1797424

/////////////////////M.h//////////////////////

namespace GSpace 

   class G;


class M

   public:
      friend class GSpace::G; // works, no error
   private:
      GSpace::G gClassMember; // errors: "M uses undefined class GSpace::G"
;
// Note that G.h includes M.h so I do not include it here, 
// instead I have it included in M.cpp

这确实有助于让班级成为朋友。但是,当我使用该类型实际声明一个类成员时,它会产生一个问题,因为该类没有定义。 GFile.h

我误解了#include 和前向声明的行为方式,还是编译器方面的某种实现问题(我假设不太可能)?

【问题讨论】:

为我工作:ideone.com/l9s72G。错误是什么? GFile.h 是否真的定义了 GSpace::G 错误是..?我敢打赌GFile.h 包含包含class M 的文件,或者您缺少include guards 并需要它们。 @DarkFalcon 我得到的错误是当我尝试在类 M 中创建 G 的成员时,G 未定义。两个文件都包含保护,并且没有循环依赖(我有成立)。我将更新我的代码以包含此错误。 @Josh:让一个类成为朋友不会将它的名字带入本地范围。您仍然需要使用命名空间对其进行限定。 @DarkFalcon 是的(忘了把它放在模型代码中,写的时候有点匆忙:/)。还有什么看起来不正确的吗? 【参考方案1】: 因为您的成员不是指针或引用,编译器需要知道G 的大小。您不能使用前向声明。 如评论中所述,您需要使用命名空间限定 G

这是为我编译的代码:

namespace GSpace

   class G
   
   ;


class M

   public:
      friend class GSpace::G;
   private:
      GSpace::G gClassMember;
;

int main() return 0;

【讨论】:

非常有意义!谢谢你。如果它是方法的参数,情况是否相同?编译器是否也需要提前知道它们的大小?它可以计算出一个参数在运行时需要多少堆栈分配? 可以前向声明方法的参数,但在声明参数类型之前不能调用该方法。这只是编译时的。 C++ 没有内置反射或元数据来允许运行时确定方法参数大小。【参考方案2】:

试试下面的

namespace GSpace

   class G;


class M

   public:
      friend class GSpace::G; 


namespace GSpace

   class G  /* definition of the class */ ;

【讨论】:

以上是关于交友/使用不同命名空间中的类的主要内容,如果未能解决你的问题,请参考以下文章

C#通过反射获取不同命名空间下的类(属性和方法)

11类加载器的命名空间

不同命名空间内的类的循环依赖 C++

php--命名空间

深入理解命名空间

尝试访问命名空间 Ui 中的类