为什么类中的方法顺序不适用于C ++?

时间:2012-06-06 23:05:28

标签: c++ compiler-construction

我用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 ++编译器如何编译上面给出的代码。

3 个答案:

答案 0 :(得分:10)

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

在您的课程中,bar2b无效,因为它们都使用了尚未声明的my_int_type

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

实际上,这是:

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

答案 1 :(得分:5)

编译器刚刚开始陷入困境。任何不熟悉的符号都将被视为未定义的新符号。这是函数定义或头文件背后的方案。

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

答案 2 :(得分:3)

它与可见性有很大关系。我认为你的困惑可能来自假设一次通过。可以将类解析分为两个阶段。

  1. 解析类定义。
  2. 解析方法实现。
  3. 这样做的好处是我们可以从类成员函数中看到整个类。