是的,您在初始化列表中使用成员函数是有效的并且符合标准。
数据成员按照它们的声明顺序进行初始化(这就是为什么它们应该按照它们的声明顺序出现在初始化列表中的原因 - 您在示例中遵循的规则)。N_
首先初始化,您可以将此数据成员传递给fill_arr
. fill_arr
在构造函数之前调用,但是因为这个函数不访问未初始化的数据成员(它根本不访问数据成员),所以它的调用被认为是安全的。
以下是 C++ 标准最新草案 (N3242=11-0012) 中的一些相关例外:
§ 12.6.2.13:可以为正在构造的对象调用成员函数(包括虚拟成员函数,10.3)。(...)但是,如果这些操作是在 ctor-initializer 中执行的(或在直接或间接调用的函数中)来自 ctor-initializer) 在基类的所有 mem-initializer 完成之前,操作的结果是未定义的。例子:
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
};
class C {
public:
C(int);
};
class D : public B, C {
int i;
public:
D() : C(f()), // undefined: calls member function
// but base C not yet initialized
i(f()) { } // well-defined: bases are all initialized
};
§12.7.1:对于具有非平凡构造函数的对象,在构造函数开始执行之前引用对象的任何非静态成员或基类会导致未定义的行为。例子
struct W { int j; };
struct X : public virtual W { };
struct Y {
int *p;
X x;
Y() : p(&x.j) { // undefined, x is not yet constructed
}
};