【问题标题】:C++ delegating ctor and parent ctor with argumentC++ 使用参数委派 ctor 和父 ctor
【发布时间】:2016-07-25 11:38:03
【问题描述】:

这似乎在 C++11 中不起作用:

class B : public A
{
  public:
    B(const A& a)
        : A(a)   // parent constructor for passing the parameter
        , B()    // delegating constructor for init of other members
    {};
  // ...
};

gcc 告诉我an initializer for a delegating constructor must appear alone

如何既调用带参数的父类的构造函数,又调用B类的基本构造函数? (我在 B 中有一堆需要相同行为的其他构造函数)。

现在我正在考虑编写一个私有 B::init() 函数并在所有构造函数体中使用它,但这有点 C++03 的味道。

首选的解决方案是什么?

【问题讨论】:

  • 为什么不往另一个方向写呢? B::B() : B(A{}) {}B::B(const A&a) : A(a), other_member{}{}.
  • @Jarod42 为什么不写答案而不是评论?
  • @Barry:不确定我是否错过了什么。

标签: c++ c++11 constructor initializer-list


【解决方案1】:

我认为委托的首选方式是相反的,它不是用来重构构造函数的公共部分,而是将更简单的部分定义为更复杂情况的特例。

所以你应该从B(const A& a) 开始并将其用作委托目标。

class B : public A
{
  public:
    B() : B(A());
    B(const A& a) : A(a)   // parent constructor for passing the parameter
    {};
};

在创建B 时,无论如何您都在调用A()

其背后的基本原理是,当您有两个“部分专业化”的 c'tors 时,您将无法使用它们来初始化复杂的 c'tors。例如:

class B : public A
{
  public:
    B() {};
    B(int) : B() {};
    B(double) : B() {};
    B(double,int) : B(int), B(double) {}; // can't do it.
};

我相信在 Bathsheba 的回答中解释了技术原因。看看如果你在B()中有一个共同的部分会发生什么:

class B : public A
{
  public:
    B() {};
    B(int) : B() {};
    B(double) : B() {};
    B(double,int) : B(int), B(double) {}; //ooops would get B() called twice!
};

这是从继承中知道的钻石问题。解决办法就是把逻辑颠倒过来。

class B : public A
{
  public:
    B() : B(0,0) {};
    B(int a) : B(a,0) {};
    B(double d) : B(0,d) {};
    B(double a, int d) {/*full implementation*/};
};

【讨论】:

  • 加一个用于提供解决方案,不像我的回答;-)
  • 貌似抄袭了巴里的评论=/。但我在它发布之前就开始写了。
  • 在我看来,这样做并没有什么坏处:cmets 是答案的可怜表亲,因为前者不容易经过同行评审,而且没有接受机制。
  • 我明白了。鉴于我现实生活中的构造函数签名的变化 B,我可能会坚持使用 B::init()...
  • @Bathsheba 是的,即使是简单的答案也需要时间和精力。
【解决方案2】:

B(const A& a) : A(a), B() 没有意义,因为B()初始化基类A。这本质上是一个重复的初始化,这是一个固有的矛盾。

如果您使用委托构造函数,该语言唯一真正的选择是禁止其他任何事情。这就是你的编译器告诉你的。

【讨论】:

  • 抱歉,评论已删除。
  • 所以这是一个冲突,因为B() 调用A(),但是我尝试调用A(a),对吗?
  • 绝对正确!你不能两次构造同一个对象。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-22
  • 2015-10-13
  • 1970-01-01
  • 2017-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多