的朋友类只需要在其他命名空间中的前向声明

的朋友类只需要在其他命名空间中的前向声明

本文介绍了为什么一个C ++的朋友类只需要在其他命名空间中的前向声明?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个类

  • 成为 G 的朋友,不需要 F 的向前声明。

  • 同样,类 A :: BF 可以是 A :: C 无前向声明

    • to be friend to A::C, F must be forward declared.
    • to be friend to G, no forward declaration of F is necessary.
    • likewise, a class A::BF can be friend to A::C without forward declaration

    以下代码说明了这一点,并使用GCC 4.5,VC ++ 10和至少一个其他编译器进行编译。

    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?

    推荐答案

    C ++ 标准 ISO / IEC 14882:2003(E)

    7.3.1.2命名空间成员定义

    7.3.1.2 Namespace member definitions


    命名空间中首次声明的每个名称都是 如果在
    a非本地类中的朋友声明首先声明一个
    类或函数
    (这意味着该类或函数的名称是不合格的)朋友类
    或函数是
    最内层命名空间的成员。

    // Assume f and g have not yet been defined.
    void h(int);
    template <class T> void f2(T);
    namespace A {
       class X {
       friend void f(X);  //  A::f(X) is a friend
          class Y {
             friend void g();  //  A::g is a friend
             friend void h(int);  //  A::h is a friend
             //  ::h not considered
             friend void f2<>(int);  //  ::f2<>(int) is a friend
          };
       };
       //  A::f, A::g and A::h are not visible here
       X x;
       void g() { f(x); }  // definition of A::g
       void f(X) { /* ... */}  // definition of A::f
       void h(int) { /* ... */ }  // definition of A::h
       //  A::f, A::g and A::h are visible here and known to be friends
    }
    


    您的朋友类BF; 在命名空间A中声明 A :: BF ,而不是全局命名空间。您需要全局预先声明以避免此新声明。

    Your friend class BF; is a declaration of A::BF in namespace A rather than global namespace. You need the global prior declaration to avoid this new declaration.

    这篇关于为什么一个C ++的朋友类只需要在其他命名空间中的前向声明?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

    08-21 18:56