为什么 C++友元类只需要在其他命名空间中进行前向声明?
假设我有一个类 F
,它应该是类 G
(在全局命名空间中)和 C
(在命名空间 A 中)的友元)。
- 要成为
A::C
的友元,F
必须前向声明。 - 要成为
G
的友元,不需要F
的前向声明。 - 同样,类
A::BF
可以是A::C
的友元,无需前向声明
以下代码说明了这一点,并使用 GCC 4.5、VC++ 10 进行编译,并且至少使用另一种编译器。
class G {
friend class F;
int g;
};
// without this forward declaration, F can't be friend to A::C
class F;
namespace A {
class C {
friend class ::F;
friend class BF;
int c;
};
class BF {
public:
BF() { c.c = 2; }
private:
C c;
};
} // namespace A
class F {
public:
F() { g.g = 3; c.c = 2; }
private:
G g;
A::C c;
};
int main()
{
F f;
}
对我来说,这似乎不一致。这是有原因的还是只是标准的设计决定?
Suppose I have a class F
that should be friend to the classes G
(in the global namespace) and C
(in namespace A
).
- to be friend to
A::C
,F
must be forward declared. - to be friend to
G
, no forward declaration ofF
is necessary. - likewise, a class
A::BF
can be friend toA::C
without forward declaration
The following code illustrates this and compiles with GCC 4.5, VC++ 10 and at least with one other compiler.
class G {
friend class F;
int g;
};
// without this forward declaration, F can't be friend to A::C
class F;
namespace A {
class C {
friend class ::F;
friend class BF;
int c;
};
class BF {
public:
BF() { c.c = 2; }
private:
C c;
};
} // namespace A
class F {
public:
F() { g.g = 3; c.c = 2; }
private:
G g;
A::C c;
};
int main()
{
F f;
}
To me this seems inconsistent. Is there a reason for this or is it just a design decision of the standard?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
C++
标准ISO/IEC 14882:2003(E)
7.3.1.2 命名空间成员定义
第 3 段
您的
friend class BF;
是命名空间 A 中的A::BF
声明,而不是全局命名空间。您需要全局事先声明来避免此新声明。C++
StandardISO/IEC 14882:2003(E)
7.3.1.2 Namespace member definitions
Paragraph 3
Your
friend class BF;
is a declaration ofA::BF
in namespace A rather than global namespace. You need the global prior declaration to avoid this new declaration.让我们考虑一下示例中的这 3 行代码:
第 7.3.1.2 段第 3 点(命名空间成员定义)中的 C++ 标准说:
第 2 行完全遵循标准要求。
所有的困惑都是因为“朋友声明”很弱,您需要提供可靠的前向声明才能进一步使用。
Let's take into account these 3 code lines from your sample:
C++ standard in paragraph 7.3.1.2, point 3 ( Namespace member definitions) says:
And line 2 follows exactly what standard requires.
All confusion is because "friend declaration" is weak, you need to provide solid forward declaration for further usage.
因为如果您位于
namespace {}
块内,那么在全局命名空间中声明某些内容是没有意义的。friend class BF;
起作用的原因是它的作用类似于隐式前向声明。Because it wouldn't make sense to be able to declare something in the global namespace if you're inside a
namespace {}
block. The reasonfriend class BF;
works is that it acts like an implicit forward declaration.