友谊范围c++

发布于 2024-08-08 23:12:48 字数 770 浏览 2 评论 0原文

Bjarne Stroustrup 在《C++ 编程语言》第 11.5.1 节中写道:

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

例如:

类矩阵
{
    朋友类Xform;
    友元矩阵求逆 (const Matrix &);
//..
 };
X 形式 x; // 错误:范围内没有 Xform
矩阵 (*p) (const Matrix &) = &invert; // 错误:范围内没有 invert()

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

然而,下一节接着说,该类必须是先前定义的,或者是在非类作用域中定义的,该作用域立即包含将其声明为友元的类。

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

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

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

In section 11.5.1 of "The C++ Programming Language", Bjarne Stroustrup writes:

Like a member declaration, a friend declaration does not introduce a name into an enclosing scope.

For example:

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

For large programs and large classes, it is nice that a class doesn’t ‘‘quietly’’ add names to its enclosing scope. For a template class that can be instantiated in many different contexts (Chapter 13), this is very important.

However, the next section then goes on to say that the class must have been previously defined, or defined in the non-class scope immediately enclosing the class that is declaring it a friend.

My question is that because of the fact that the class needs to be previous defined or defined in the nonclass scope immediately enclosing the class that is declaring it a friend, then in the first example Xform could not be out of scope, as presumably the class would have been defined before the definition of the Matrix class. Furthermore, I can't think of a situation which, given the restriction that the friend class needs to be previously defined or defined immediately after the granter's class, that the friend class will not be in scope!

Secondly, is my interpretation of Bjarne in this section correct, in that:

  • For friend CLASSES only, friend class must have been previously defined in an enclosing scope, OR defined immediately after the non-class scope.
  • For a function, must have been previously declared in an enclosing scope, OR it can also be found by having an argument of type == 'the friendship granter's' class?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

_蜘蛛 2024-08-15 23:12:48

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

这就是整个独立示例。它不仅仅是一个摘录,您应该在给定代码之前或之后想象其他代码,例如 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 未在那里声明。相反,友元声明必须引用将在程序中其他位置的命名空间 N 中定义的其他 AE 类。 (但是,它根本不需要在任何地方定义;类可以说它们是不存在的事物的朋友,程序不会关心。不过程序员会关心的,因为他们会浪费时间试图在源代码中找到正确的 AE 类。)

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

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

You're right that Xform would need to have been defined before Matrix if the example code was supposed to work. But it wasn't supposed to work. It was an example of bad code — code that tried to have the friend declaration introduce new names into the program, and then use those names to declare a variable and initialize a pointer.

That was the entire standalone example. It wasn't just an excerpt where you were supposed to imagine additional code before or after the given code, such as definitions for Xform and invert.

Your first paraphrase is not quite correct. The definition of the friend class does not need to immediately follow the class who granted it friendship. It needs to be defined in the immediately enclosing scope. Essentially, it should be defined in the same scope as the class it's friends with. The example after the one you cite illustrates it:

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
}

Although Y says that AE is its friend, it's not referring to the AE class declared earlier because namespace N is the immediately enclosing scope of Y and AE isn't declared there. Instead, the friend declaration must refer to some other AE class that's going to be defined in namespace N elsewhere in the program. (However, it doesn't need to be defined anywhere at all; classes can say they are friends with things that don't exist, and the program won't care. The programmers will care, though, because they'll waste time trying to find the right AE class in the source code.)

You're also wrong on your second paraphrase. The function doesn't have to have been previously declared in an enclosing scope. It just has to be declared eventually. Consider the opening example of section 11.5, where operator* is listed as a friend of both Vector and Matrix classes before the operator has been either declared or defined.

Furthermore, for the friend function to be found, it doesn't have to have arguments equal to the class's type. Stroustrup says the function "can be found through its arguments," and then refers you to section 8.2.6 for what he means by that. That's the section on name lookup.

谜兔 2024-08-15 23:12:48

当 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
}

这是正确的吗?

An example of when Matrix is in scope, XForm isn't, yet there is an XForm class defined which is the friend of 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
}

Is this correct?

伴随着你 2024-08-15 23:12:48

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

对于函数,情况类似。然而,有一个区别,它甚至可以用友元声明(=在 Matrix 类内部)定义,并且正如您所说,“通过具有 == ' 类型的参数来找到友谊授予者的类”(或具有作为其嵌套类的参数类型),由 Koenig 查找。

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.

温柔少女心 2024-08-15 23:12:48

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

定义为朋友的东西必须在其他地方定义,否则它就不是朋友——什么都不是——它不存在。

是这个问题吗?

The idea of a friend function is when you have a private class so that normally other classes cannot access what's inside - you're making a black box, BUT you want to specifically name functions that are outside that are exceptions to that rule. I think it should be thought of as not having much to do with scope, or if anything, defining a special kind of scope.

Something defined as a friend would have to be defined elsewhere, otherwise it's not a friend - it's nothing - it doesn't exist.

Was that the question?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文