在 gcc 中使用朋友类

Posted

技术标签:

【中文标题】在 gcc 中使用朋友类【英文标题】:Use friend class in gcc 【发布时间】:2019-08-02 16:19:44 【问题描述】:

我有这个在 VC14 中编译的类,但是当我尝试在 gcc 4.8.5 中编译时,它不起作用,我得到“错误:C 未在此范围内声明”。

class A


;

class B : public A

   friend class C;
   friend class D;
private:
   class BB
   
      std::list<C> c;
      std::list<D> d;
   ;
;

class C : public B::BB


;

class D : public B::BB


;

我试图在 B 类的定义之前转发声明“C 类”,但它给了我一个错误,因为它没有与“C 类:公共 B::BB”相同的定义,我不能不放那个定义,因为 BB 是私有的……我不知道该怎么做。

谢谢

【问题讨论】:

friend class BB ... 这是一个错字吗?你不能像那样声明/实现一个类作为朋友。 请提供minimal reproducible example。 (另外,“C++11”不是编译器。) 是的,打错了,抱歉 恕我直言,friend 类增加了复杂性。你可以在不需要friend 的情况下重新设计吗? 这不能用任何 C++ 编译器编译,因为 ...、缺少分号、缺少 List 的定义等。这不是真正的代码。我们不知道真正的问题是什么,因为我们看不到真正的代码。 【参考方案1】:

使用friend 的前向声明与其他前向声明不同。在B 的定义中写入friend class C; 声明在封闭的命名空间(全局命名空间)中有一个名为C 的类,但实际上并没有将名称 C 引入该范围。因此,您不能写像List&lt;C&gt; 这样的东西,因为找不到名称C。你应该这样做:

class C;
class D;
class B : public A

   friend class C;
   friend class D;
private:
   class BB
   
      List<C> c;
      List<D> d;
   

命名空间范围声明实际上将名称CD 引入全局范围。然后,朋友声明使这些类成为B 的朋友。

【讨论】:

为什么它“在 C++11 中编译”(不管那是什么意思)? VS在这里会出现一些不符合项吗?尽管我认为我们首先需要一个更好的问题,但这可能是对答案的一个有价值的补充。【参考方案2】:

在你这样做的时候

List<C> c;
List<D> d;

编译器不知道CD 是什么——你还没有声明/实现它们!

您不必完全实现它们,但您至少需要告诉编译器它们是将在某个时候实现的类。你可以这样做:

class C;
class D;

完整的工作示例(带有一些小的修复,例如添加分号以使其编译):ideone

【讨论】:

我尝试这样做,与您的示例相同,我可以在 gcc 8 中编译它,但不能在 gcc 4.8.5 中编译。它说“B类::BB”是私有的。是编译器版本的原因吗? 完整错误是“class B::BB' is private in this context 'class C: public B::BB'”。

以上是关于在 gcc 中使用朋友类的主要内容,如果未能解决你的问题,请参考以下文章

gcc 编译错误:模板类表中嵌套类 A ​​的成员在嵌套朋友类中不可见。为啥?

如何静态链接到 libstdc++.喜欢升级的GCC的朋友快来看看

C ++中的朋友保护方法

从 GCC 获取优化的源代码

两级嵌套 c++ 类适用于 GCC,但使用 Clang 失败

GCC 问题:使用依赖于模板参数的基类成员