【问题标题】:friendship scope c++友谊范围 C++
【发布时间】:2010-12-10 17:06:52
【问题描述】:

在“C++ 编程语言”的第 11.5.1 节中,Bjarne Stroustrup 写道:

与成员声明一样,友元声明不会将名称引入封闭范围。

例如:

class Matrix
{
    friend class Xform;
    friend Matrix invert (const Matrix &);
//..
 };
Xform x; // error: no Xform in scope
Matrix (*p) (const Matrix &) = &invert; // error: no invert() in scope

对于大型程序和大型类,一个类不会“悄悄地”将名称添加到其封闭范围是很好的。对于可以在许多不同上下文中实例化的模板类(第 13 章),这一点非常重要。

但是,下一节接着说,该类必须是先前定义的,或者定义在非类范围内,立即包含声明它为友元的类。

我的问题是,由于该类需要预先定义或定义在非类范围内,立即封闭声明它为朋友的类,那么在第一个示例中,Xform 不能超出范围,因为该类可能会在定义 Matrix 类之前定义。此外,考虑到朋友类需要预先定义或在授予者类之后立即定义的限制,我想不出这样的情况,朋友类将不在范围内!

其次,我在本节中对 Bjarne 的解释是否正确,因为:

  • 仅对于友元类,友元类必须先前已在封闭范围中定义,或者在非类范围之后立即定义。
  • 对于函数,必须先前已在封闭范围内声明,或者也可以通过类型 == '友谊授予者' 类的参数找到它?

【问题讨论】:

    标签: c++ scope friend access-control


    【解决方案1】:

    我不知道我是否理解你的问题,但我认为 Bjarne 认为如果你想使用它,你需要在 Matrix 之外定义类(比如 Xform)(想象它是你放置的一些帮助类在你没有#include 在所有.cpp 文件中#include 带有Matrix 的文件的头文件中)。如果您从不提及它,则无需定义它:)

    在函数的情况下,情况类似。但是,有一个区别,它甚至可以用朋友声明(=在Matrix类中)定义,正如你所说,“通过具有类型=='友谊授予者'类的参数来找到” (或具有作为其嵌套类的参数类型),通过 Koenig 查找。

    【讨论】:

      【解决方案2】:

      友元函数的概念是当您拥有一个私有类时,通常其他类无法访问其中的内容 - 您正在制作一个黑匣子,但您想专门命名该规则例外的外部函数.我认为它应该被认为与范围没有太大关系,或者如果有的话,定义一种特殊的范围。

      定义为朋友的东西必须在别处定义,否则它不是朋友 - 它什么都不是 - 它不存在。

      是这个问题吗?

      【讨论】:

        【解决方案3】:

        你说得对,Xform 需要在 Matrix 之前定义如果示例代码应该工作。但它不应该工作。这是一个错误代码的例子——试图让友元声明在程序中引入新名称,然后使用这些名称来声明一个变量并初始化一个指针。

        这就是整个独立示例。这不仅仅是一个摘录,您应该在给定代码之前或之后想象其他代码,例如 Xforminvert 的定义。

        您的第一个解释不太正确。朋友类的定义不需要立即跟随授予它友谊的类。它需要在立即封闭的范围中定义。本质上,它应该定义在与它的朋友类相同的范围内。您引用的示例之后的示例说明了这一点:

        class AE { /* ... */ }; // not a friend of Y
        
        namespace N {
          class X { /* ... */ }; // Y's friend
        
          class Y {
            friend class X;
            friend class Z;
            friend class AE;
          };
        
          class Z { /* ... */ }; // Y's friend
        }
        

        虽然YAE 是它的朋友,但它并不是指前面声明的AE 类,因为命名空间NY 的直接封闭范围,而AE 没有在那里声明.相反,friend 声明必须引用一些 other AE 类,该类将在程序的其他地方的命名空间 N 中定义。 (然而,它根本需要在任何地方定义;类可以说它们是不存在的事物的朋友,程序不会在意。不过程序员会在意,因为他们会浪费时间试图在源代码中找到正确的 AE 类。)

        你的第二个解释也错了。该函数不必以前在封闭范围内声明。它只需要最终声明。考虑第 11.5 节的开头示例,其中operator* 被列为VectorMatrix 类的朋友运算符被声明或定义之前。

        此外,要找到友元函数,它的参数不必等于类的类型。 Stroustrup 说该函数“可以通过它的参数找到”,然后请您参阅第 8.2.6 节以了解他的意思。这是关于名称查找的部分。

        【讨论】:

        • 我想我理解 Bjarne 想要表达的观点。如果朋友存在,那么上面定义了它存在于哪个范围内。我的困惑是,假设 XForm 是一个朋友,我想不出一个例子,其中 Matrix 会在范围内,而 XForm 不会。我已将我认为发生这种情况的示例附加到此问题的末尾。
        • 如果我理解正确,您是说友元函数已在封闭范围内声明。 Bjarne 写道:“因此友元函数应该在封闭范围内显式声明或接受其类的参数” 那么在 11.5.2 之前的示例中,为什么 f() 不是 X 的友元?它看起来像是在一个直接封闭的范围内(全局范围): void g(); X类{朋友无效f();朋友无效 g(); }; void f() {/* */} // 不是 X 的友元,但是 this 不是在直接包含 X 声明的范围内定义(和声明)的吗?
        【解决方案4】:

        一个例子,当 Matrix 在范围内时,XForm 不在,但定义了一个 XForm 类,它是 Matrix 的朋友:

        1.h
        ------------------------
        namespace Foo
        {
         class Matrix
         {
          friend class XForm;
         };
        }
        
        1.c
        ------------------------
        #include 1.h
        // XForm not in scope
        // implement Matrix
        
        2.h
        ------------------------
        namespace Foo
        {
         class XForm
         {
         };
        }
        
        main.c
        
        #include 1.h
        #include 2.h
        int main()
        {
         // both XForm & Matrix in scope here
        }
        

        这对吗?

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-07-01
          • 2023-03-14
          • 2014-01-13
          • 2011-11-19
          • 1970-01-01
          相关资源
          最近更新 更多