面试题答案
一键面试成员变量初始化顺序
- 父类成员变量:在
Derived
类对象初始化时,首先调用Base
类的构造函数。在Base
类构造函数执行前,Base
类的成员变量baseVar
会被初始化。这里Base
类构造函数中baseVar
使用derivedVar + b
进行初始化,然而此时derivedVar
尚未初始化。 - 子类成员变量:在
Base
类构造完成后,才会初始化Derived
类的成员变量derivedVar
。
潜在问题
由于Base
类构造函数中使用了尚未初始化的derivedVar
来初始化baseVar
,这会导致未定义行为。因为derivedVar
在Base
类构造函数执行时其值是不确定的,可能是垃圾值,从而导致baseVar
被初始化为一个错误的值。
改进方法
- 调整参数顺序:修改
Derived
类构造函数参数顺序,使得derivedVar
相关计算所需的值在Base
类构造函数调用前已确定。例如:
class Base {
int baseVar;
public:
Base(int b) : baseVar(b) { }
};
class Derived : public Base {
int derivedVar;
public:
Derived(int d, int b) : derivedVar(d), Base(d + b) { }
};
- 使用临时变量:先计算出
baseVar
所需的值,再传递给Base
类构造函数。
class Base {
int baseVar;
public:
Base(int b) : baseVar(b) { }
};
class Derived : public Base {
int derivedVar;
public:
Derived(int b, int d) : derivedVar(d) {
int temp = derivedVar + b;
Base(temp);
}
};
这样能确保baseVar
在初始化时使用的是已确定的值,避免未定义行为。