【问题标题】:virtual inheritance with abstract class constructors带有抽象类构造函数的虚拟继承
【发布时间】:2011-11-17 09:22:29
【问题描述】:

我遇到了以下问题:有一个抽象基类,另外两个抽象类实际上继承自基类,作为结论,必须调用它的构造函数,并带有所有需要的参数。

但是现在,我得到了一个“普通”类,它确实继承了两个二阶类,因此必须自己调用基类构造函数(因为基类实际上是从两个二阶类继承的),但是两个二阶构造函数都带参数传递给基类构造函数。

是否有可能以一种不需要传递那些在这种情况下未使用的参数的方式实现构造函数?

我希望我能够准确地描述我的问题,如果有任何问题我会很乐意回答。

【问题讨论】:

  • 听起来你很努力地描述它,但如果你能敲出一个小代码示例,它可能会帮助我们更好地理解你在做什么,以便提供更好的答案:)跨度>
  • 听起来像struct base { base(char a) {} virtual func()=0;}; struct derived1 : public virtual base { derived1() : base('a') {} func() {} }; struct derived2 : public virtual base { derived2() : base('b') {} func() {} }; struct derived3 : public derived1, derived2 { derived3() : derived1(), derived2(), base('c') {} };?
  • 我喜欢疯狂的代码评论 :)
  • 嗯,原来我对虚拟继承的了解不够,无法回答这个问题。去学习了!
  • 我唯一的想法是将受保护的构造函数添加到两个派生类中,以表示它们不必构造基类,但是查看标准,我看不到任何澄清问题的内容。

标签: c++ oop


【解决方案1】:

终于找到了。

§ 12.6.2 / 7 [class.base.init]

使用了 mem-initializer 中的表达式列表或大括号初始化列表 初始化指定的子对象(或者,在 委托构造函数,完整的类对象)根据 8.5 的初始化规则用于直接初始化。这 每个 mem-initializer 执行的初始化构成一个 充分表达。 mem-initializer 中的任何表达式都被评估为 执行初始化的完整表达式的一部分。 一个 mem-initializer,其中 mem-initializer-id 表示虚拟基础 在执行任何类的构造函数期间忽略类 不是派生最多的类。

所以,传递参数。无论如何,它们都会被忽略。让事情变得非常简单!

【讨论】:

  • 嗯,好的!必须这样做,但我实际上希望有一些方法可以解决这个问题,以便我可以设计短而精确的构造函数。
  • 您还可以创建不接受这些参数的受保护构造函数,以便从派生类中使用。
  • 一个很好的问题是,为什么需要它,即使调用这个构造函数的情况是不可能的。例如,为什么要求抽象类中的构造函数初始化虚拟基(即当虚拟基具有带参数的构造函数时,则无法合成该抽象类中的默认构造函数,必须显式提供)。当从派生类调用时,它不会被调用,因为派生类无论如何都必须初始化虚基本身。否则它不会被调用,因为该类是抽象的。
  • @Ethouris:可悲的是,答案是,将这种情况的异常写入 C++ 规范可能不值得。 “基类没有默认构造函数,中间类是虚拟的和抽象的”可能不会经常出现。
  • @MooingDuck:这很简单,如果类是抽象的,那么声明对于虚拟基类的基类构造函数的构造函数委托被忽略(并且不需要提供)就足够了。应该有人忘记了这一点。
猜你喜欢
  • 2015-06-21
  • 1970-01-01
  • 1970-01-01
  • 2013-10-24
  • 2020-06-19
  • 2012-12-19
  • 1970-01-01
  • 1970-01-01
  • 2023-03-14
相关资源
最近更新 更多