在“The C ++ Programming Language”的第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的解释是正确的,其中:
答案 0 :(得分:2)
如果示例代码可以正常工作,那么Xform
之前需要定义Matrix
你是对的。但它不应该工作。这是 bad 代码的一个例子 - 代码试图让friend声明在程序中引入新名称,然后使用这些名称来声明变量并初始化指针。
这就是整个独立的例子。这不仅仅是您应该在给定代码之前或之后想象其他代码的摘录,例如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声明必须引用一些其他 AE
类,这些类将在程序中其他地方的名称空间N
中定义。 (但是,它根本不需要需要定义;类可以说它们是不存在的东西的朋友,程序也不关心。程序员会关心,虽然,因为他们会浪费时间在源代码中找到合适的AE
类。)
你的第二个释义你也错了。该函数不必在封闭范围内声明先前。它只需要声明最终。考虑第11.5节的开头示例,其中operator*
在声明或定义运算符之前被列为Vector
和Matrix
类的朋友。
此外,对于要找到的友元函数,它不必具有与类的类型相等的参数。 Stroustrup说这个函数“可以通过它的参数找到”,然后引用你的第8.2.6节来了解它的含义。这是关于名称查找的部分。
答案 1 :(得分: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
}
这是对的吗?
答案 2 :(得分:0)
我不知道我是否理解你的问题,但我认为Bjarne认为你需要在Xform
之外定义一个类(如Matrix
),如果你想使用它(想象它是一些你放在一个头文件中的助手类,你在#include
所有.cpp
个文件中都没有Matrix
#include包含Matrix
的文件。如果你从未提及它,你无需定义它:)
如果是功能,情况类似。但是,有一个区别,它甚至可以使用友元声明(= {{1}}类中)来定义,并且,正如您所说,“通过使用类型=='的参数找到友谊格的''通过Koenig查找“。”(或者具有作为其嵌套类的参数类型)。
答案 3 :(得分:0)
友元函数的想法是当你有一个私有类时,通常其他类不能访问里面的东西 - 你正在制作一个黑盒子,但是你想要专门命名那些在该规则之外的函数。我认为它应该被认为与范围无关,或者如果有的话,定义一种特殊的范围。
定义为朋友的东西必须在别处定义,否则它不是朋友 - 它什么都不是 - 它不存在。
那是个问题吗?