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

I am compiling a class, the complete program to which is given below:

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

The code works absolutely fine, but how is the constructor able to access the variable width which has not been declared until the end of public block. Also, how are the member functions able to access the variables declared later in the public block? Isn't C++ sequential (executing the statements in the order they are written)?



Solution 1:[1]

Think of inline definitions in a class as just syntactic sugar for declaring the function, and then defining outside of the class. Manually doing that would transform the code to

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

And you can see from this transformation that the class member is now "before" the function definitions, so there is no reason why they can't know about the variable.

The technical term for this is call the complete-class context and the jist of it is that when you are in the body of a member function or the class member initialization list, the class is considered complete and can use anything defined in the class, no matter where in the class it is declared.

Solution 2:[2]

This is because the body of a member function is a complete-class context of a class, as mentioned in the quoted statements below:

From 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.

The above means that a function body is a complete-class context of a class which in turn means that the usage of width inside the constructor and the usage of height inside member function setHeight and printHeight is allowed here even though those data members appear later when writing the class definition.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Anoop Rana