为什么 C++需要类成员的前向声明吗?

发布于 2024-12-04 03:07:11 字数 391 浏览 2 评论 0原文

我的印象是 C++ 中的所有内容都必须在使用之前声明。

事实上,我记得读到过,这就是为什么在返回类型中使用 auto 在没有 decltype 之类的情况下是无效的 C++0x 的原因 >:编译器在计算函数体之前必须知道声明的类型。

想象一下当我注意到(很长一段时间后)以下代码实际上完全合法时我的惊讶:

[编辑:更改了示例。]

class Foo
{
    Foo(int x = y);
    static const int y = 5;
};

所以现在我不明白:

为什么编译器不这样做当在其他地方需要它们时,需要在类内部进行前向声明吗?

I was under the impression that everything in C++ must be declared before being used.

In fact, I remember reading that this is the reason why the use of auto in return types is not valid C++0x without something like decltype: the compiler must know the declared type before evaluating the function body.

Imagine my surprise when I noticed (after a long time) that the following code is in fact perfectly legal:

[Edit: Changed example.]

class Foo
{
    Foo(int x = y);
    static const int y = 5;
};

So now I don't understand:

Why doesn't the compiler require a forward declaration inside classes, when it requires them in other places?

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

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

发布评论

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

评论(5

南巷近海 2024-12-11 03:07:11

该标准规定(第 3.3.7 节):

在类中声明的名称的潜在范围不仅包括名称声明点之后的声明区域,还包括所有函数体、非静态数据成员的大括号或等于初始化程序以及默认值该类中的参数(包括嵌套类中的此类内容)。

这可能是通过将内联成员函数的处理主体延迟到解析整个类定义之后来完成的。

The standard says (section 3.3.7):

The potential scope of a name declared in a class consists not only of the declarative region following the name’s point of declaration, but also of all function bodies, brace-or-equal-initializers of non-static data members, and default arguments in that class (including such things in nested classes).

This is probably accomplished by delaying processing bodies of inline member functions until after parsing the entire class definition.

北斗星光 2024-12-11 03:07:11

类体内的函数定义被视为在类定义之后实际定义。所以你的代码相当于:

class Foo
{
    Foo();
    int x, *p;
};
inline Foo::Foo() { p = &x; }

Function definitions within the class body are treated as if they were actually defined after the class has been defined. So your code is equivalent to:

class Foo
{
    Foo();
    int x, *p;
};
inline Foo::Foo() { p = &x; }
那支青花 2024-12-11 03:07:11

其实我觉得你需要把问题倒过来才能理解。

为什么 C++ 需要前向声明?

由于 C++ 的工作方式(包括文件,而不是模块),否则它需要等待整个翻译单元才能评估,当然,什么函数是。这里有几个缺点:

  • 编译时间将再次受到影响,
  • 几乎不可能为标头中的代码提供任何保证,因为后面函数的任何引入都可能使其全部无效

为什么类不同?

根据定义,类是包含的。这是一个小单位(或者应该是......)。因此:

  • 几乎没有编译时间问题,您可以等到类结束才开始分析,
  • 没有依赖地狱的风险,因为所有依赖项都被清楚地识别和隔离

,因此我们可以避免这种烦人的类前向声明​​规则。

Actually, I think you need to reverse the question to understand it.

Why does C++ require forward declaration ?

Because of the way C++ works (include files, not modules), it would otherwise need to wait for the whole Translation Unit before being able to assess, for sure, what the functions are. There are several downsides here:

  • compilation time would take yet another hit
  • it would be nigh impossible to provide any guarantee for code in headers, since any introduction of a later function could invalidate it all

Why is a class different ?

A class is by definition contained. It's a small unit (or should be...). Therefore:

  • there is little compilation time issue, you can wait until the class end to start analyzing
  • there is no risk of dependency hell, since all dependencies are clearly identified and isolated

Therefore we can eschew this annoying forward-declaration rule for classes.

冷弦 2024-12-11 03:07:11

只是猜测:编译器保存函数体,并且在类声明完成之前不会实际处理它。

Just guessing: the compiler saves the body of the function and doesn't actually process it until the class declaration is complete.

无人问我粥可暖 2024-12-11 03:07:11

与命名空间不同,类的作用域不能重新打开。它是绑定的。

想象一下,如果所有内容都需要提前声明,那么在标头中实现一个类。我认为由于它是绑定的,因此按原样编写语言更符合逻辑,而不是要求用户在类中向前编写(或要求定义与声明分开)。

unlike a namespace, a class' scope cannot be reopened. it is bound.

imagine implementing a class in a header if everything needed to be declared in advance. i presume that since it is bound, it was more logical to write the language as it is, rather than requiring the user to write forwards in the class (or requiring definitions separate from declarations).

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