【问题标题】:Duplicating base-class constructors to subclass?将基类构造函数复制到子类?
【发布时间】:2009-09-30 22:54:30
【问题描述】:

我有大量的类,我需要将它们“包装”在一个非常薄的子类中。基类的功能没有改变,它们的接口保持不变。

问题是,为了使用基类的构造函数(而且大多数都有多个),我需要在每个子类中贴上相同的构造函数,然后简单地将参数传递给基类(99% 的时间我在施工时无事可做)。这是很多无意义的工作。

最简单的方法是什么?

编辑:即使该语言本身不支持它,也许有一些工具可以自动生成该代码?

【问题讨论】:

  • 一个代码示例可能会有所帮助。你在做类似Subclass() : BaseClass(params) { } 的事情吗?
  • @Nick:是的。 subclass(param1,param2,param3) : baseclass(param1,param2,param3) {}

标签: c++ inheritance constructor


【解决方案1】:

您可以为包装类中的所有可能参数添加模板构造函数:

template<class Base>
class wrapper : public Base {
public:
  wrapper() : Base() {}

  template<typename T1>
  wrapper(T1 a1) : Base(a1) {}

  template<typename T1, typename T2>
  wrapper(T1 a1, T2 a2) : Base(a1, a2) {}

  // ...
};

由于不会为未调用的构造函数实例化模板,因此这些其他构造函数是否无效并不重要。只有实际使用的构造函数需要存在于基类中:

class A {
public:
  A(int a) {};
};

int main() {
   wrapper<A> aw(1);
   return 0;
}

可能在某些极端情况下,这种方法会导致问题,但对于简单的情况,它是有效的。

【讨论】:

    【解决方案2】:

    除非您可以使用 C++0x,否则我认为您很不走运。阅读这篇文章:

    Automatic creation of constructor, based on parent class' constructor (C++)

    【讨论】:

      【解决方案3】:

      一厢情愿让我建议

      class BaseClass {
      public:
          BaseClass(foo, bar, baz);
      };
      
      template <class T>
      class BaseInheritor : public BaseClass {
      public:
          T(foor, bar, baz);
      };
      
      class Child : public BaseInheritor<Child> {
          // Other stuff
      };
      

      不幸的是,我认为 C++ 模板不能完全完成我刚刚编写的工作。宏有一个非常简单的答案,但我觉得建议它很脏:

      #define CHILD_CLASS_DEFAULT(name) \
      class name : public BaseClass { \
          public: name(foo, bar, baz) : BaseClass(foo, bar, baz) { } \
          private:
      
      
      #define CHILD_CLASS_OVERRIDE(name) \
      class name : public BaseClass { \
      

      【讨论】:

      • 那不行,因为有很多基类,每个都有不同的构造函数集(带不同的参数)。
      • 这让我想到了涉及每个基类 2 或 3 个宏定义以及一些标记粘贴的技巧。会很丑的。
      【解决方案4】:

      我会选择基于脚本的解决方案,可能基于 gccxml 或类似的东西。
      有了它,您可以编写一个简单的脚本(即generate-derivate &lt;input-file&gt; &lt;base-name&gt; &lt;derivative-name&gt; &lt;output-file&gt;)来生成包装器。如果您要添加/更改功能,则只需手动进行更改。

      编辑:模糊的轮廓:

      write derivative-name + " : public " + base-name + " {\npublic:\n"
      foreach <Constructor> where attribute name == base-name
          write "\tderivate-name("
          foreach <Argument>
             resolve by attribute type (query FundamentalType, ReferenceType, ...)
             write argument type etc.
          write ");\n"
      write "\n};\n"
      

      这完全取决于您使用的脚本语言和 xml 工具。奇趣科技在 their example 中有 XQuery。

      【讨论】:

      • 这似乎是一个解决方案。但是我从未使用过 gccxml。你能给出这样一个脚本的大纲吗?
      猜你喜欢
      • 1970-01-01
      • 2013-06-23
      • 2018-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-24
      • 2014-09-13
      相关资源
      最近更新 更多