【问题标题】:How to access a class constructor parameter from the another class parameter如何从另一个类参数访问类构造函数参数
【发布时间】:2020-07-11 09:14:52
【问题描述】:

与 C++ 构造函数参数斗争

所以,我刚从 TS/JS/Py 出来,并试图理解 C++ 概念。但是我正在努力使用 FOR 类的构造函数的参数来声明参数的默认值。这是我要运行的代码:

double Phythagorean_Hypotenuse (int& a, int& b ) {
    return sqrt((a * a) + (b * b));
};

class Triangle {
    public:
      int a;
      int b;
      double c;
      Triangle(int a_param, int b_param, double c_param = Phythagorean_Hypotenuse(a_param, b_param)) {
            a = a_param;
            b = b_param;
            c = c_param;
      }
};

主函数内部

Triangle mytri_1(10, 20);
std::cout << mytri_1.a << std:endl;

但是当我尝试运行这段代码时,IDE 会抛出一些错误,例如

[Error] 'a_param' was not declared in this scope

[Error] call to 'Triangle::Triangle(int, int, double)' uses the default argument for parameter 3, which is not yet defined

那么,请问有谁能解决这个问题吗?

谢谢。

【问题讨论】:

  • 也很抱歉,对于糟糕的混乱代码,我对此很陌生,但仍在学习。

标签: c++ class parameters constructor arguments


【解决方案1】:

有一些问题会阻止您的代码编译,即:

  1. 构造函数没有返回类型。
  2. double c_param = Phythagorean_Hypotenuse(a_param, b_param) 对参数无效,a_param, b_param 将无法识别。

建议更改:

由于假设计算的结果很可能是十进制值,所以c 应该是double

你可以这样做:

Running sample

#include <iostream>
#include <cmath>

double Phythagorean_Hypotenuse (int& a, int& b ) {
    return sqrt((a * a) + (b * b));
};

class Triangle {
    public:
      int a;
      int b;
      double c; //should be double

      //initializer list is a good practice for member initialization
      Triangle(int a_param, int b_param) 
          : a(a_param), b(b_param), c(Phythagorean_Hypotenuse(a, b)) {} 
};

int main(){

    Triangle mytri_1(10, 20);
    std::cout << mytri_1.a << std::endl;
    std::cout << mytri_1.b << std::endl;
    std::cout << mytri_1.c << std::endl;
}

输出:

10
20
22.3607

【讨论】:

  • 谢谢,我真的感谢您的帮助,@anastaciu。
  • @azizbekmasharibov,谢谢你的朋友,很高兴我的回答对你有所帮助。
【解决方案2】:

正如编译器所指出的,其他构造函数参数不能用作 c_param 参数的默认参数。与其使用默认值,不如重载构造函数,包括一个只接受 2 个参数的构造函数。然后这个构造函数可以调用另一个接受所有 3 个的构造函数:

 // Constructor overload that accepts all 3 parameters
 Triangle(int a_param, int b_param, double c_param):
  a(a_param), b(b_param), c(c_param) {
  }

  // Constructor overload that accepts just a and b, call the other constructor
  // to set all 3 members
  Triangle(int a_param, int b_param):
  Triangle(a_param, b_param, Phythagorean_Hypotenuse(a_param, b_param)) {
  }

【讨论】:

    【解决方案3】:

    默认参数值不能引用其他参数。您可以定义两个重载,其中一个委托给另一个,以执行您想要的操作:

    class Triangle {
    public:
        double a;
        double b;
        double c;
    
        Triangle(double a_param, double b_param, double c_param)
            : a{a_param},
              b{b_param},
              c{c_param}
        {}
    
        Triangle(double a_param, double b_param)
            : Triangle{a_param, b_param, Phythagorean_Hypotenuse(a_param, b_param)}
        {}
    };
    

    Live Demo


    其他几点说明:

    • 类构造函数没有返回类型。我将void Triangle(...) 更改为Triangle(...)
    • 我在构造函数的主体中使用了构造函数初始化列表而不是赋值。对于像 ints 或 doubles 这样的小的原始值可能没有区别,但这是一个好习惯,可以对更复杂的类型产生很大的影响
    • intc 的类型没有意义(或 ab 就此而言)。三角形的边不可能都是整数
    • 没有理由通过引用将参数传递给Pythagorean_Hypotenuse。按值传递它们更简单,可能更快

    【讨论】:

    • 哇,感谢您的清晰解释,非常感谢。总之,非常感谢@Miles Budnek!
    猜你喜欢
    • 2018-06-23
    • 1970-01-01
    • 2017-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-23
    相关资源
    最近更新 更多