首页 > 解决方案 > C++ 初始值设定项列表成员仍在调用默认构造函数?

问题描述

我在初始化shared_ptr我正在处理的类的成员时遇到问题。

我有两个班级,A并且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;
}

我只想让 classB持有一个std::shared_ptrclass 的实例A。但是,我no matching function for call to A::A()B的构造函数中遇到了错误。

我很困惑,因为我认为初始化列表的重点是避免隐式调用成员变量的默认构造函数,但它似乎仍然试图调用A的默认构造函数。

任何解释表示赞赏,谢谢。

编辑:经过更多的混乱,如果B不继承自A. 仍然不确定为什么继承 fromA会导致A从 ' 的构造函数中调用 ' 的默认构造B函数。

标签: c++initializationshared-ptrinitializer-list

解决方案


既然B是从 派生的A,那么每一个B都是一个A。这意味着要构造 a B,您还必须构造 a A。但是,您不告诉B' 构造函数如何构造A,因此使用默认构造函数。

如果你想BA并且只持有一个shared_ptrto A,那么A一定不要做任何你不想B做的事情。在这里,A_x_y

目前尚不清楚你真正想要什么,但也许你想要一些其他的基类,它们都AB从它派生的只有两者AB应该有的东西。

C++ 中继承的经典示例就像Instrument是基类,其成员Play与派生类类似Trumpet,并且Clarinet具有使某些特定工具成为小号的东西。只有Trumpets 和Clarinets 共有的内容才应该在Instrument.


推荐阅读