Initialization
- If a given non-static data member has both a brace-or-equal-initializer and a mem-initializer, the initialization specified by the mem-initializer is performed, and the non-static data member’s brace-or-equal-initializer is ignored. Example:
struct A {
int i = /* some integer expression with side effects */ ;
A(int arg) : i(arg) { }
// ...
};
the A(int) constructor will simply initialize i to the value of arg, and the side effects in i’s brace-orequal-initializer will not take place.
int idx = 0;
class A {
public:
A(int i): i_(i) {
cout << i_ << "\n"; // 10
}
int i_ = idx++; // idx++ side effect will not take place
};
int main() {
A a(10);
cout << a.i_ << "\n"; // 10
cout << idx << "\n"; // still 0
}
- Names in the expression-list or braced-init-list of a mem-initializer
are evaluated in the scope of the constructor for which the mem-initializer is specified.
The this pointer can be used in the expression-list of a mem-initializer to refer to the object being initialized. Example:
class X {
int i;
int j;
public:
X(int i): i(i), j(this->i) { }
};
- Member functions (including virtual member functions) can be called for an object under construction. Similarly, an object under construction can be the operand of the typeid operator
or of a dynamic_cast.
However, if these operations are performed in a ctor-initializer (or in a function called directly or indirectly from a ctor-initializer) before all the mem-initializers for base classes have completed,
the result of the operation is undefined. Example:
class A {
public:
A(int);
};
class B : public A {
int j;
public:
int f();
B() : A(f()), // undefined: calls member function
// but base A not yet initialized
j(f()) { } // well-defined: bases are all initialized
};
- A mem-initializer followed by an ellipsis is a pack expansion that initializes the base classes specified by a pack expansion in the base-specifier-list for the class.
Example:
template<class... Mixins>
class X : public Mixins... {
public:
X(const Mixins&... mixins) : Mixins(mixins)... { }
};
本文详细解释了在C++中初始化成员变量时,当存在 brace-or-equal 初始化和 mem 初始化时,mem 初始化的优先级更高。通过具体例子展示了如何避免副作用,并介绍了 this 指针在 mem 初始化中的使用。同时,阐述了构造函数内调用成员函数、使用 typeid 和 dynamic_cast 的限制条件,以及 mem 初始化中 pack 扩展的概念。
1761

被折叠的 条评论
为什么被折叠?



