Class member without a default constructor

…衆ロ難τιáo~ 提交于 2019-12-18 08:32:06

问题


Suppose I have a class A without a default constructor, a factory method factoryA that returns an object of type A, and a class B that has A as its member. I know that in this case the member of type A of B has to be initialize in B's constructor initialization list. It is not entirely clear to me why so if someone could explain that to me it would be great. Also, what if the parameter to A's constructor needs to be computed inside of B's constructor, say by querying a database or something of that nature? Is there a way to use the setup below without providing A with a default constructor? Thanks in advance.

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);
  }
};

回答1:


Member objects are always initialized before entry into the body (the part between the curly braces) of the constructor. If you don't mention a member in the initializer list, it gets default constructed. So mention it!

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

This calls the function factoryA with the argument value true if j is greater than 0 and false otherwise, and initializes the member _a with the value returned by that call.




回答2:


It is not entirely clear to me why so if someone could explain that to me it would be great.

For classes[*], the _a = factoryA(true); line calls _a.operator=(factoryA(true)). Calling a member function on _a requires _a to already be initialised. So if it weren't a compile-time error, it still wouldn't be valid.

Also, what if the parameter to A's constructor needs to be computed inside of B's constructor, say by querying a database or something of that nature? Is there a way to use the setup below without providing A with a default constructor?

As long as A has a copy or move constructor, you can initialise it with a function return value, and that function can do anything you want, even using different constructors for A depending on the arguments provided.

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);
}

[*] I know, there are exceptions.




回答3:


In this case it's better to use the pointer to A, i.e. A* _a, and then call A constructor wherever you want.



来源:https://stackoverflow.com/questions/12328150/class-member-without-a-default-constructor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!