【问题标题】:c++ call superclass constructor with calculated argumentsc++ 使用计算参数调用超类构造函数
【发布时间】:2012-03-02 19:56:03
【问题描述】:

可能非常简单,但是有人可以告诉我如何使用在子类的构造函数中计算的参数来调用超类的构造函数吗?像这样:

class A{
  A(int i, int j);
};

class B : A{
  B(int i);
};

B::B(int i){
  int complex_calculation_a= i*5;
  int complex_calculation_b= i+complex_calculation_a;
  A(complex_calculation_a, complex_calculation_b);
}

//编辑:我编辑了示例,以便超类接受两个相互关联的参数

【问题讨论】:

    标签: c++ inheritance constructor


    【解决方案1】:

    如果你不能用单行表达式表达你的计算,添加一个静态函数,并以你通常调用超类的构造函数的方式调用它:

    class B : A{
    public:
        B(int i) : A(calc(i)) {};
    private:
        static int calc(int i) {
            int res = 1;
            while (i) {
                res *= i--;
            }
            return res;
        }
    };
    

    EDIT多参数情况:

    class B : A{
    public:
        B(int i) : A(calc_a(i), calc_b(i)) {};
    private:
        static int calc_a(int i) {
            int res = 1;
            while (i) {
                res *= i--;
            }
            return res;
        }
        static int calc_b(int i) {
            int complex_a = calc_a(i);
            return complex_a+10;
        }
    };
    

    【讨论】:

    • 好的 - 如果超类构造函数接受多个参数?
    • @Mat 您需要定义单独的函数来计算您不能或不想“内联”为表达式的每个参数的值。
    • 但是计算出来的参数可能相互依赖——我如何用不同的函数来解决这个问题?
    • @Mat 不幸的是,您需要多次重复相同的计算。我在答案中添加了一个示例。
    【解决方案2】:
    B::B(int i) 
        : A(i * 5) 
    {}
    

    对于 C++11,一个更复杂的方法是

    B::B(int i)
        : A(([](int x) { return 5 * x; })(i))
    {}
    

    对于复杂的情况,受保护的init 函数更具可读性。

    【讨论】:

      【解决方案3】:

      只有这样:

      class A{
        A(int i);
      };
      
      class B : A{
        B(int i);
      };
      
      B::B(int i) : A(i*5) {
      }
      

      对父构造函数的调用只能在初始化列表中。这意味着,无论您要计算什么,都必须在 B 完全构造之前知道(即:您不能调用 B 成员函数,除非它的 static,但只能依赖传递给B的参数)

      【讨论】:

      • 好的——在这种情况下,我的例子很糟糕。我需要做几个函数调用、循环、条件分支等来计算参数
      • @Mat - 正如我所说 - 您只能在外部函数中执行此操作(全局或静态类成员,或传递给 B 的对象的成员函数)。调用 A 时,B 不存在。
      【解决方案4】:
      struct A
      {
          A(int);
      };
      
      struct B : public A
      {
          B()
              : A(5) // "initialisation list"
          {}
      };
      

      您必须在列表中执行此操作,但您可以使用函数。 编辑:如果你使用一个函数,你可能想让它成为 B 的私有静态成员。

      【讨论】:

        【解决方案5】:
        class A
        {
        public:
           A(int i){}
        };
        
        
        class B : public A
        {
        public:
            B(int i):A(i*5){}
        };
        

        【讨论】:

          猜你喜欢
          • 2012-05-02
          • 2013-07-19
          • 1970-01-01
          • 1970-01-01
          • 2013-12-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多