【问题标题】: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
}

在对 StackOverflow 进行了一番研究之后,我找到了这个答案https://stackoverflow.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 是的(忘了把它放在模型代码中,写的时候有点匆忙:/)。还有什么看起来不正确的吗?

标签: c++ header namespaces friend


【解决方案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 */ };
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-03
    • 2013-04-17
    • 1970-01-01
    • 2011-04-20
    • 1970-01-01
    • 2010-12-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多