Search code examples
c++initializationshared-ptrinitializer-list

C++ initializer list members still calling default constructor?


I'm having a problem initializing a shared_ptr member of a class I'm working on.

I have two classes, A and B:

class A {
  int _x;
  int _y;

  public:
    A(int, int);
};

A::A(int x, int y) {
  _x = x;
  _y = y;
}

class B : public A {
  std::shared_ptr<A> _a;

  public:
    B(std::shared_ptr<A>);
};

B::B(std::shared_ptr<A> a) : _a(a) {}

int main() {
  std::shared_ptr<A> a = std::make_shared<A>(1, 2);

  B b(a);

  return 0;
}

I just want class B to hold a std::shared_ptr to an instance of class A. However, I'm getting the error no matching function for call to A::A() in B's constructor.

I'm confused because I thought the point of the initializer list is to avoid implicitly calling the default constructor for member variables, but it still seems to be trying to call A's default constructor.

Any explanation is appreciated, thanks.

edit: after more messing around, it seems like it complies properly if B does not inherit from A. Still unsure why inheriting from A results in A's default constructor being called from B's constructor.


Solution

  • Since B is derived from A, every B is an A. That means to construct a B, you must also construct an A. However, you do not tell B's constructor how to construct an A, so the default constructor is used.

    If you want B to be derived from A and only hold a shared_ptr to A, then A must not do anything you don't want B to do. Here, A has _x and _y.

    It's not clear what you really want, but perhaps you want some other base class that both A and B derive from that only has what both A and B should have.

    The classic example of inheritance in C++ is something like Instrument being the base class that has members like Play with derived classes like Trumpet and Clarinet having the thing that makes some particular instrument a trumpet. Only what is common to Trumpets and Clarinets should be in Instrument.