3

我用 C++ 编程已经有一段时间了,直到今天我才想到这个。

考虑以下代码:

struct foo
{
  // compiles fine
  void bar()
  {
    a = 1;
    my_int_type b;
    b = 5;
  }

  // Just a declaration, this fails to compile, which leads me to assume that
  // even though the bar() method is declared and defined all at once, the
  // compiler looks/checks-syntax-of the class interface first, and then compiles
  // the respective definitions...?
  void bar2(my_int_type); // COMPILE ERROR

  my_int_type       b; // COMPILE ERROR because it comes before the typedef declaration
  typedef int       my_int_type;
  my_int_type       a;

  void bar3(my_int_type); // compiles fine
};

int main()
{
  foo a;
  a.bar();
  return 0;
}

我对错误发生原因的理解(见bar2()上面的评论)是否正确/不正确?无论哪种方式,我都希望能简单地概述一下单程 C++ 编译器如何编译上面给出的代码。

4

3 回答 3

10

在大多数情况下,C++ 文件是从上到下解析的,因此必须在使用实体之前声明它们。

在您的班级中,bar2并且b无效,因为它们都使用my_int_type尚未声明的 。

“从上到下”解析规则的一个例外是在其类的定义中定义的成员函数。当解析这样的成员函数定义时,它被解析为好像它出现在类的定义之后。这就是您使用my_int_typeinbar有效的原因。

实际上,这:

struct foo
{
    void bar()
    {
        my_int_type b;
    }

    typedef int my_int_type;
};

是相同的:

struct foo
{
    void bar();

    typedef int my_int_type;
};

inline void foo::bar()
{
    my_int_type b;
}
于 2012-06-06T23:09:29.603 回答
5

编译器刚开始在一个块中下降。任何不熟悉的符号都将被视为未定义的新符号。这是函数定义或头文件背后的方案。

您可以假设编译器首先创建了一个定义列表,因此 bar() 方法应该被正确编译,因为之前已经提供了定义。

于 2012-06-06T23:08:57.983 回答
3

这与能见度有很大关系。我认为您的困惑可能来自假设一次通过。认为类解析分两个阶段完成。

  1. 解析类定义。
  2. 解析方法实现。

这样做的好处是我们可以从类成员函数中看到整个类。

于 2012-06-06T23:26:05.300 回答