1

STRUGGLING WITH C++ CONSTRUCTOR ARGUMENTS

So, I've just came from TS/JS/Py and trying to understand C++ concepts. But I'm struggling with using the parameter of constructor of the class FOR declaring default value for an argument. Here is the code I'm trying to run:

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;
      }
};

and inside of the main function

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

But when I try to run this code, IDE is throwing me some errors like

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

or

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

So, please, can someone who can fix this answer the question?

Thanks.

1
  • 1
    and also sorry guys, for poorish messy code, I'm pretty noob at this, but still learning. Commented Mar 30, 2020 at 22:40

3 Answers 3

2

There are some issues that prevent your code from compiling, namely:

  1. Constructors do not have return type.
  2. double c_param = Phythagorean_Hypotenuse(a_param, b_param) is not valid for a parameter, a_param, b_param will not be recognized.

Recommend change:

Since the result of a hypothenuse calculation will most likely be a decimal value, c should be a double.

You can do something like this:

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;
}

Output:

10
20
22.3607
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, I really appreciate your help, @anastaciu.
@azizbekmasharibov, thank you my friend, I'm glad my answer helped you.
2

As the compiler is pointing out, the other constructor arguments are not available as default parameters for the c_param argument. Rather than using default values, just overload the constructor, including one that just accepts 2 parameters. This constructor can then invoke the other constructor that accepts all 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)) {
  }

Comments

2

Default parameter values cannot reference other parameters. You can define two overloads, one of which delegates to the other, to do what you want:

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


A few other notes:

  • Class constructors do not have a return type. I changed void Triangle(...) to Triangle(...)
  • I used constructor initialization lists instead of assignment in the constructor's body. There's likely no difference for small primitive values like ints or doubles, but it's a good habit to get into and can make a big difference for more complex types
  • int doesn't make sense for the type of c (or a or b for that matter). The sides of a triangle are unlikely to all be integers
  • There's no reason to pass parameters to Pythagorean_Hypotenuse by reference. It's simpler and likely faster to pass them by value

1 Comment

Wow, thanks for that clear explanation, really appreciate it. In short, thanks so much, @Miles Budnek!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.