【问题标题】:dynamic base class constructor call in derived class constructor in c++C++派生类构造函数中的动态基类构造函数调用
【发布时间】:2020-11-28 22:19:12
【问题描述】:

我在一个库中有一个基类,出于兼容性原因我不想修改它。该类存储了某些构造后无法修改的设置;必须在构造时提供正确的参数。

我自己的代码包含一个派生自该类的类。派生类的构造函数的参数结构与基类的构造函数不同;参数不是简单地传递给基类构造函数。

有三组预定的参数将用于从派生类构造基类。关于使用这三个中的哪一个的决定取决于派生类构造函数的参数。由于成员初始化器列表中需要基类参数,因此需要在进入派生构造函数的主体之前做出此决定。

在这种情况下,使用需要为 Arduino (Mega) 编译的代码来实现这一点最优雅的是什么?

演示设置的伪代码:

class base{
    base(type1 arg1, type2 arg2){/*do something*/}
};

class derived : base{
    int variable;
    derived(typeA a, typeB b, int c) :
    // if a,b match first scenario:
    base(1, 2) 
    // if a,b match second scenario:
    base(3, 4) 
    // if a,b match third scenario:
    base(1, 4) 
    {
        variable = c;
    }
};

【问题讨论】:

  • 这是很多词来混淆描述可以通过代码示例布局的东西。哎呀,有时只是尝试将代码示例放在一起,您就会找到解决方案。
  • 好吧,你想到了什么样的代码?带有构造函数的基类和派生类?除此之外,我不想将任何代码放入我原来的问题中,因为这正是我所要求的部分。但是,如果您发现我的问题如此令人困惑,那么可能是告诉我它有什么令人困惑的地方,而不是简单地投反对票。这样我就可以澄清我的意思,我们俩都不必写不是很有帮助的评论。
  • 抱怨投​​反对票刚刚为您赢得了另一票投反对票。如果您需要本网站的帮助,请与我们合作并为我们提供足够的信息来了解问题。
  • @exit 你在哪里被要求提供代码示例以减少混乱,并继续抱怨没有被告知什么是混乱的。你的伪代码清除了你的文本墙中有一堆不清楚的东西。当有人要求你付出更多的努力,而你的回应是被冒犯时,你会被人嫌弃的。总之,希望我的回答对你有用。
  • 我认为文本令人困惑的地方在于它将几个概念混杂在一起,形成了一个混乱的混乱局面,相当于spaghetti code 的语言。我试着把事情分开来让它更清楚。我希望我没有在这个过程中改变问题。

标签: c++ inheritance constructor arduino derived-class


【解决方案1】:
class derived: base{
private:
    int variable;
    struct args {type1 arg1;type2 arg2;};
    static args build ( typeA& a, typeB& b );// make the decision
    derived(args&& x, int c)// delegeted only
        :base{std::move(x.arg1),std::move(x.arg2)}
        ,variable(c){};
public:
    derived(typeA a, typeB b, int c)// delegating ctor
        :derived(build(a,b),c){};
};

【讨论】:

    【解决方案2】:
    class base{
      base(int arg1, int arg2){/*do something*/}
    };
    template<auto i>
    using val_t=std::jntegral_constant<dedktype(i), i>;
    template<auto i>
    constexpr val_t<i> val={};
    
    class derived : base{
      int variable;
      derived(val_t<0>):base(1,2){}
      derived(val_t<1>):base(3,4){}
      derived(val_t<2>):base(1,4){}
      static derived helper(arg a, arg b, arg c){
        if (case 1) return derived(val<0>);
        if (case 2) return derived(val<1>);
        if (case 3) return derived(val<2>);
      }
    public:
      derived(arg a, arg b, arg c) :
        derived(helper(a,b,c))
      {
        variable = c;
      }
    };
    

    顺便说一句,在您发布伪代码之前,我无法确定您想要什么。

    这里我们使用一个辅助静态函数,它可以在它选择调用哪个 ctor 之前包含复杂的逻辑。 我们有不完整的 ctor 用于构建我们的基础。

    真正的 ctor 调用 helper,然后在 helper 构建基础后运行它的主体。

    这使用来自 委托ctors 和constexpr 模板变量。它可以在纯 中完成。它还使用来自 的保证省略,否则您需要复制或移动ctor。

    【讨论】:

      【解决方案3】:

      在这种情况下,用于构建 derived 实例的辅助函数可能更适合您。

      class derived : base{
          int variable;
          derived(char a, char b, int c) : base(a, b), variable(c) { }
      
      public:
          static derived build(int a, int b, int c) {
              if(/* a,b match first scenario */) {
                  return dervied("w", "x", c);
              }
              else if(/* a,b match second scenario */) {
                  return dervied("x", "y", c);
              }
              else if(/* a,b match third scenario */) {
                  return dervied("1", "2", c);
              }
              else {
                  throw std::runtime_error("Bad arguments");
              }
          }
      };
      

      这使您可以在构建 derived 之前分析任何参数,并扩展您的 base

      【讨论】:

      • 如果我正确理解了您的代码,这将调用基类构造函数并且其输出将被忽略。之后,您第二次调用构造函数,从您构建函数,对吗?然而,不幸的是,在第一次调用基类构造函数时,参数必须完全正确,因为使用错误参数值的调用可能会导致硬件损坏。我会将这些信息添加到我的主要问题中。
      • 不,这会在每次调用 build 时构造一个 derivedderived 的构造函数调用 base 的构造函数,通过传递 char 参数而不进行修改。
      • 编辑了示例以显示 ifs 并更清楚地说明每次调用仅构建一个 derived(以及扩展为 base)。
      • 对,对不起。我忽略了static 修饰符。我试试看。
      【解决方案4】:

      最简单的解决方案是通过在传入之前计算参数来将参数传递给基本ctor in。

      Derived::Derived(char x, char y, int a) : Base(x , y) {
      variable =a;
      }
      

      否则我认为您可以定义一个 constexpr 函数,该函数将获取您的 int 值并给出您想要的字符并在 ctor 中调用它。

      【讨论】:

        猜你喜欢
        • 2015-08-18
        • 2016-07-19
        • 2018-07-21
        • 2018-07-16
        • 1970-01-01
        • 1970-01-01
        • 2020-09-22
        • 2014-11-17
        • 1970-01-01
        相关资源
        最近更新 更多