0

在“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 的解释是否正确,因为:

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

4 回答 4

2

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

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

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

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
}

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

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

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

于 2009-10-28T01:59:06.837 回答
1

一个例子,当 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
}

这个对吗?

于 2009-10-29T00:15:07.120 回答
0

I don't know if I understand your question, but I think Bjarne thought you need to define the class (say Xform) outside Matrix if you want to use it (imagine it is some helper class you put in a header file that you don't #include in all .cpp files that #include the file with Matrix). You needn't define it if you never mention it :)

In case of functions, the situation is similar. However, there is a difference, that it can be even defined with the friend declaration (=inside the Matrix class) and, as you say, "be found by having an argument of type == 'the friendship granter's' class" (or have argument type that is a nested class thereof), by Koenig lookup.

于 2009-10-28T01:15:34.183 回答
0

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

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

是这个问题吗?

于 2009-10-28T01:26:18.063 回答