【问题标题】:What is the order of control flow while compiling the code for a class in C++?在 C++ 中为类编译代码时控制流的顺序是什么?
【发布时间】:2021-05-02 13:40:04
【问题描述】:

我正在编译一个类,完整的程序如下:

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

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

【问题讨论】:

  • 声明不是陈述。在尝试编译其代码之前,会收集和存储类的声明。此外,如果程序的可观察行为在“as-if”规则下是相同的,AFAIK,则不需要顺序执行语句。
  • “C++ 不是顺序的(按照它们编写的顺序执行语句)吗?” 不,不是。语句可以按不同的顺序执行,例如成员初始化器列表。语句按照成员在类中列出的顺序执行,而不是按照实际语句的顺序执行。
  • 声明为int height{};,这样用户就不能在没有setHeight()的情况下尝试printHeight()来调用未定义的行为。
  • 在调用构造函数之前初始化成员变量(int width = 6;)。这意味着在调用第一个非静态方法之前必须知道类的结构。
  • Here 你可以看到在实际的构造函数开始工作之前发生了什么。有更好的文档,但我找不到它们。

标签: c++ oop control-flow access-specifier


【解决方案1】:

将类中的内联定义视为声明函数的语法糖,然后在类外部进行定义。手动这样做会将代码转换为

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

你可以从这个转换中看到,类成员现在“在”函数定义之前,所以他们没有理由不知道变量。

这方面的技术术语是调用complete-class context,它的意思是当你在一个成员函数的主体或类成员初始化列表中时,这个类被认为是完整的并且可以使用任何定义在类,无论它在类中的哪个位置声明。

【讨论】:

  • 在构造函数的初始化列表中也是如此吗?
  • @VincentFourmond 是的。成员初始化列表被认为是函数体的一部分
  • 谢谢@NathanOlivier 我想这对你的回答来说是一个有价值的精确度?
  • @VincentFourmond 添加了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-27
  • 2019-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多