7

假设我有一个没有默认构造函数的 A 类,一个返回 A 类型对象的工厂方法 factoryA,以及一个以 A 作为其成员的 B 类。我知道在这种情况下,B 的类型 A 的成员必须在 B 的构造函数初始化列表中进行初始化。我不完全清楚为什么,如果有人可以向我解释,那就太好了。另外,如果 A 的构造函数的参数需要在 B 的构造函数内部计算,比如通过查询数据库或类似的东西怎么办?有没有办法在不为 A 提供默认构造函数的情况下使用下面的设置?提前致谢。

class A {
private:
  int _i;
public:
  A(int i) : _i(i) {} 
};

A factoryA(bool b) {
  if(b)
    return A(1);
  else return A(2);
}

class B {
private:
  A _a;
public:
  B(int j) {
    if(j > 0)
      _a = factoryA(true);
    else _a = factoryA(false);
  }
};
4

3 回答 3

9

成员对象总是在进入构造函数的主体(大括号之间的部分)之前被初始化。如果你没有在初始化列表中提到一个成员,它会被默认构造。所以提一下!

B::B(int j) : _a(factoryA(0 < j)) { };

如果factoryA参数值大于 0,否则将调用函数,并使用该调用返回的值初始化成员。truejfalse_a

于 2012-09-08T12:49:53.053 回答
6

我不完全清楚为什么,如果有人可以向我解释,那就太好了。

对于类[*],该_a = factoryA(true);行调用_a.operator=(factoryA(true)). 调用成员函数_a需要_a已经初始化。因此,如果它不是编译时错误,它仍然是无效的。

另外,如果 A 的构造函数的参数需要在 B 的构造函数内部计算,比如通过查询数据库或类似的东西怎么办?有没有办法在不为 A 提供默认构造函数的情况下使用下面的设置?

只要A有一个复制或移动构造函数,您就可以使用函数返回值对其进行初始化,并且该函数可以做任何您想做的事情,甚至A根据提供的参数使用不同的构造函数。

class B {
private:
  A _a;
  static A getA(int i);
public:
  B(int j) : _a(getA(j)) {
  }
};

A B::getA(int j)
{
  if (j > 0)
    return factoryA(true);
  else
    return factoryA(false);
}

[*] 我知道,也有例外。

于 2012-09-08T06:41:26.817 回答
0

在这种情况下,最好使用指向 A 的指针,即 A* _a,然后在任何需要的地方调用 A 构造函数。

于 2012-09-08T05:03:02.637 回答