在 C++ 中编译 class 的代码时,控制流的顺序是什么?

What is the order of control flow while compiling the code for a class in C++?

我正在编写一个class,完整的程序如下:

#include<iostream>
using namespace std;

class Test{
    public:
        Test()
        {
            cout<<"Test variable created...\n";
            // accessing width variable in constructor
            cout<<"Width is "<<width<<".\n";
        }
        void setHeight(int h)
        {
            height = h;
        }
        void printHeight()
        {
            cout<<"Height is "<<height<<" meters.\n";
        }
        int width = 6;
    protected:
        int height;
};

int main()
{
    Test t = Test();
    t.setHeight(3);
    t.printHeight();
    return 0;
}

代码工作得很好,但是构造函数如何能够访问直到 public 块结束才声明的变量 width。此外,成员函数如何能够访问稍后在 public 块中声明的变量? C++ 不是顺序的(按照语句写入的顺序执行语句)吗?

将 class 中的内联定义视为声明函数的语法糖,然后在 class 外部进行定义。手动执行此操作会将代码转换为

class Test{
    public:
        Test();
        void setHeight(int h);
        void printHeight();
        int width = 6;
    protected:
        int height;
};

Test::Test()
{
    cout<<"Test variable created...\n";
    // accessing width variable in constructor
    cout<<"Width is "<<width<<".\n";
}

void Test::setHeight(int h)
{
    height = h;
}

void Test::printHeight()
{
    cout<<"Height is "<<height<<" meters.\n";
}

并且您可以从这个转换中看到 class 成员现在位于函数定义的“之前”,因此他们没有理由不知道该变量。

这个的技术术语是调用complete-class context,它的要点是当你在成员函数的主体或class成员初始化列表中时,class 被认为是完整的,可以使用 class 中定义的任何内容,无论它在 class 中的何处声明。

这是因为成员函数的主体是 class 的 complete-class 上下文 ,如下面引述的语句所述:

来自class.mem.general#6

6. A complete-class context of a class is a:

  • function body ([dcl.fct.def.general]),

  • default argument,

  • noexcept-specifier ([except.spec]), or

  • default member initializer

within the member-specification of the class.

上面的意思是函数体是class的complete-class上下文,这反过来意味着width在构造函数中的用法和[=11的用法=] 内部成员函数 setHeightprintHeight 在这里是允许的,即使这些数据成员在编写 class 定义时稍后出现。