【问题标题】:Can I do something so that arguments to superconstructor are passed implicitly?我可以做一些事情来隐式传递超级构造函数的参数吗?
【发布时间】:2016-01-14 16:04:02
【问题描述】:

我有一种情况,顶级类需要一个参数,而没有一个子类需要。某类:

class SuperClass {
public:
    SuperClass(const int parameter);
}

这是孩子:

class NoParametersInConstructorClass : public SuperClass {
public:
    // This will cause an error:
    // error: no matching function for call to 'SuperClass::SuperClass(const int)'
    NoParametersInConstructorClass() : someText("Hello") {};
private:
    std::string someText
}

现在我面临的问题是我确实有一个初始化列表,但我发现重写所有子类中的参数很乏味。我很懒,我知道。我希望它能够在没有明确定义的情况下工作:

// Works even though NoParametersInConstructorClass(const int) isn't defined
NoParametersInConstructorClass variable(66);

当然,如果没有办法,那就没有办法,但是有吗?

【问题讨论】:

  • 你能告诉我们你的实际代码吗?子类似乎没有继承基类,所以我不确定我是否理解你的问题。你可以在子类中显式调用超类构造函数SuperClass(5)
  • 假设你的孩子继承自 base 需要一个参数,当你不给它一个参数时,你想如何调用它的构造函数?编译器应该使用随机数吗?
  • @JameyD 对不起,我忘了写: public SuperClass。我目前正在使用显式调用。我的实际代码与您看到的几乎相同,只是名称为GraphBigGraph 和sevelar 相似,参数为GraphData*。所以我猜不需要再看更多实际的代码了。
  • 您可以只从基类构造函数中删除参数,并在该基构造函数中使用一个常数,这样每个派生类也可以使用一个常数。如果每个派生类的参数需要不同,那么没有其他方法。
  • 听起来像是一个坏继承的例子。派生类真的满足多态的is-a要求吗?如果基类真的需要那个参数,子类怎么能忽略呢?

标签: c++ oop inheritance constructor


【解决方案1】:

所有派生类都必须将一些值传递给基类。派生类很容易在protected 部分中的基类中拥有一个默认构造函数。您可以初始化对派生类有意义的基类成员数据。

class SuperClass {
  public:
    SuperClass(const int parameter);
  protected:
    SuperClass() : SuperClass(10) {} // Delegate to the other constructor.
}

【讨论】:

    【解决方案2】:

    如果你的问题是你有一组孩子,所有这些孩子都需要使用相同的默认参数调用SuperClass构造函数,你需要做的就是引入一个无参数构造函数的中介,这将使用幻数调用SuperClass::SuperClass

    【讨论】:

      【解决方案3】:

      将参数设为默认值。

      class SuperClass {
      public:
          SuperClass(const int parameter = DEFAULT);
      }
      

      然后您可以选择将构造函数包含在初始化列表中,或使用默认值。

      默认值:

      class NoParameterChildDefault : public SuperClass
      {
      public:
         NoParameterChildDefault() : someText("Hello") { ... } // uses value DEFAULT.
      };
      

      显式值:

      class NoParameterChildExplicit : public SuperClass
      {
      public:
        NoParameterChildExplicit() : SuperClass(5), someText("Hello") { ... } // uses value '5'.
      };
      

      【讨论】:

        【解决方案4】:

        你可能想改变你的默认子构造函数:

        class NoParametersInConstructorClass : public SuperClass {
        public:
            NoParametersInConstructorClass(int n =0) : SuperClass(n)someText("Hello") {};
         private:
            std::string someText
        }
        

        这样NoParametersInConstructorClass variable(66);NoParametersInConstructorClass variable; 都可以工作。

        【讨论】:

          【解决方案5】:

          要回答您编辑的问题: 可以使用using关键字让派生类使用基类构造函数:

          class NoParametersInConstructorClass : public SuperClass {
          public:
              using SuperClass::SuperClass;
              NoParametersInConstructorClass() : someText("Hello") {};
          private:
              std::string someText
          }
          

          您必须以某种方式为派生类定义一个构造函数。没有using 语句,您不能只调用派生类的基类构造函数。

          【讨论】:

            【解决方案6】:

            假设您不能(或者您不会)修改基类以添加默认构造函数,您必须在每个派生的初始化列表中以其有效形式(带参数)调用基类的构造函数类(如here

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2012-06-11
              • 1970-01-01
              • 2011-04-21
              • 1970-01-01
              • 2019-03-18
              • 2010-10-21
              • 2013-09-14
              • 1970-01-01
              相关资源
              最近更新 更多