成员初始值设定项的顺序
Order of member initializers
下面的代码给出了正确的输出,如果我声明变量 i
和 j
,比如 int i, j;
class A
{
int i, j;
public:
A(int val) : i(val), j(i + 1)
{
cout<<i<<endl<<j<<endl;
}
};
但是如果我声明变量 i
和 j
,比如 int j, i;
。然后 j
打印 垃圾值 .
class A
{
int j, i;
public:
A(int val) : i(val), j(i + 1)
{
cout<<i<<endl<<j<<endl;
}
};
所以,是否取决于变量声明的顺序?
Is it depend on order of declaration of variables?
是的,数据成员的顺序(即:class A
中的i
和j
) 已初始化,对应于它们被声明的顺序,而不是它们出现在构造函数的成员初始化列表中的顺序.
您的构造函数的成员初始化列表在 class A
A(int val) : i(val), j(i + 1)
没有说明这些数据成员的初始化顺序。
如果 j
在 i
之前声明(即:int j, i
),数据成员 j
仍将在 i
之前初始化。在那种情况下 j
正在被初始化为 i + 1
,但是此时 i
未初始化,这可能导致 j
包含垃圾。
在 GCC 中,您可以通过提供 -Wreorder
选项在这些情况下显示警告,该选项已通过传递 -Wall
选项启用。
Is it depend on order of declaration of variables?
是的,数据成员总是按照声明的顺序初始化,这与成员初始化列表的顺序无关。
这意味着对于您的第二个代码片段,j
总是在 i
之前初始化;但是当它被成员初始化器初始化时 i
仍然没有初始化。
对象的完整 initialization order 是:
(强调我的)
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
Is it depend on order of declaration of variables?
当然!标准忽略了初始化器在初始化列表中出现的顺序;只有声明的顺序很重要。这样做是为了 "reverse order of initialization" 在析构函数中有意义,即使可能有多个构造函数的初始化列表以不同的顺序排列。
这是 C++ 标准 (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 ]
下面的代码给出了正确的输出,如果我声明变量 i
和 j
,比如 int i, j;
class A
{
int i, j;
public:
A(int val) : i(val), j(i + 1)
{
cout<<i<<endl<<j<<endl;
}
};
但是如果我声明变量 i
和 j
,比如 int j, i;
。然后 j
打印 垃圾值 .
class A
{
int j, i;
public:
A(int val) : i(val), j(i + 1)
{
cout<<i<<endl<<j<<endl;
}
};
所以,是否取决于变量声明的顺序?
Is it depend on order of declaration of variables?
是的,数据成员的顺序(即:class A
中的i
和j
) 已初始化,对应于它们被声明的顺序,而不是它们出现在构造函数的成员初始化列表中的顺序.
您的构造函数的成员初始化列表在 class A
A(int val) : i(val), j(i + 1)
没有说明这些数据成员的初始化顺序。
如果 j
在 i
之前声明(即:int j, i
),数据成员 j
仍将在 i
之前初始化。在那种情况下 j
正在被初始化为 i + 1
,但是此时 i
未初始化,这可能导致 j
包含垃圾。
在 GCC 中,您可以通过提供 -Wreorder
选项在这些情况下显示警告,该选项已通过传递 -Wall
选项启用。
Is it depend on order of declaration of variables?
是的,数据成员总是按照声明的顺序初始化,这与成员初始化列表的顺序无关。
这意味着对于您的第二个代码片段,j
总是在 i
之前初始化;但是当它被成员初始化器初始化时 i
仍然没有初始化。
对象的完整 initialization order 是:
(强调我的)
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
Is it depend on order of declaration of variables?
当然!标准忽略了初始化器在初始化列表中出现的顺序;只有声明的顺序很重要。这样做是为了 "reverse order of initialization" 在析构函数中有意义,即使可能有多个构造函数的初始化列表以不同的顺序排列。
这是 C++ 标准 (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 ]