问题
Following code gives correct output, If I declare variables i
and j
, Like int i, j;
class A
{
int i, j;
public:
A(int val) : i(val), j(i + 1)
{
cout<<i<<endl<<j<<endl;
}
};
But If I declare variable i
and j
, like int j, i;
. then j
print garbage value.
class A
{
int j, i;
public:
A(int val) : i(val), j(i + 1)
{
cout<<i<<endl<<j<<endl;
}
};
So, Is it depend on order of declaration of variables?
回答1:
Is it depend on order of declaration of variables?
Yes, the data members are always initialized in the order of their declarations, which has nothing to do with the order of the member initializer lists.
That means for your 2nd code snippet, j
is always initialized before i
; but when it's initialized by member initializer i
is still not initialized.
The complete initialization order for the object is:
(emphasis mine)
The order of member initializers in the list is irrelevant: the actual order of initialization is as follows:
1) If the constructor is for the most-derived class, virtual base classes are initialized in the order in which they appear in depth-first left-to-right traversal of the base class declarations (left-to-right refers to the appearance in base-specifier lists)
2) Then, direct base classes are initialized in left-to-right order as they appear in this class's base-specifier list
3) Then, non-static data members are initialized in order of declaration in the class definition.
4) Finally, the body of the constructor is executed
回答2:
Is it depend on order of declaration of variables?
Absolutely! The order in which initializers appear on the initialization list is disregarded by the standard; only the order of declaration matter. This is done so that "reverse order of initialization" be meaningful in the destructor, even though potentially there may be multiple constructors with initializer lists arranged in different order.
Here is the relevant portion of the C++ standard (12.6.2.10):
In a non-delegating constructor, initialization proceeds in the following order:
- First, and only for the constructor of the most derived class (1.8), virtual base classes are initialized in the order they appear on a depth-first left-to-right traversal of the directed acyclic graph of base classes, where “left-to-right” is the order of appearance of the base classes in the derived class base-specifier-list.
- Then, direct base classes are initialized in declaration order as they appear in the base-specifier-list (regardless of the order of the mem-initializers).
- Then, non-static data members are initialized in the order they were declared in the class definition (again regardless of the order of the mem-initializers).
- Finally, the compound-statement of the constructor body is executed.
[ Note: The declaration order is mandated to ensure that base and member subobjects are destroyed in the reverse order of initialization. — end note ]
回答3:
Is it depend on order of declaration of variables?
Yes, the order in which data members (i.e.: i
and j
in your class A
) are initialized, corresponds to the order in which they are declared and not the order as they appear in the constructor's member initializer list.
Your constructor's member initializer list in class A
A(int val) : i(val), j(i + 1)
says nothing about the order in which these data members are initialized.
The data member j
will still be initialized before i
if j
is declared before i
(i.e.: int j, i
). In that case j
is being initialized to i + 1
, but i
is uninitialized at this moment, which may result in j
containing garbage.
In GCC you can get a warning being displayed in these cases by providing the -Wreorder
option, which is already enabled by passing the -Wall
option.
来源:https://stackoverflow.com/questions/45835809/order-of-member-initializers