友谊范围c ++

时间:2009-10-28 00:50:41

标签: c++ scope friend access-control

在“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的解释是正确的,其中:

  • 仅限朋友CLASSES,朋友类必须先前已在封闭范围内定义,或者在非类范围之后立即定义。
  • 对于一个函数,必须先前在封闭范围内声明,或者也可以通过类型为=='friendship grater's'类的参数找到它?

4 个答案:

答案 0 :(得分:2)

如果示例代码可以正常工作,那么Xform 之前需要定义Matrix你是对的。但它不应该工作。这是 bad 代码的一个例子 - 代码试图让friend声明在程序中引入新名称,然后使用这些名称来声明变量并初始化指针。

这就是整个独立的例子。这不仅仅是您应该在给定代码之前或之后想象其他代码的摘录,例如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
}

虽然Y表示AE是它的朋友,但它并不是指之前声明的AE类,因为名称空间NY的直接封闭范围并且AE未在此处声明。相反,friend声明必须引用一些其他 AE类,这些类将在程序中其他地方的名称空间N中定义。 (但是,它根本不需要需要定义;类可以说它们是不存在的东西的朋友,程序也不关心。程序员会关心,虽然,因为他们会浪费时间在源代码中找到合适的AE类。)

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

此外,对于要找到的友元函数,它不必具有与类的类型相等的参数。 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)

友元函数的想法是当你有一个私有类时,通常其他类不能访问里面的东西 - 你正在制作一个黑盒子,但是你想要专门命名那些在该规则之外的函数。我认为它应该被认为与范围无关,或者如果有的话,定义一种特殊的范围。

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

那是个问题吗?