Quadratic equation solver using classes (?)

So I'm a 15 yo who is trying to learn how to code in C++ using a tutorial book (I will be attending to programming classes 1 year later and thought that some skills would come in handy, plus that I like it so far). Anyways here is my problem.

I took the concept of classes and friend classes and functions and decided to use those 2 (class and friend function) to make a quadratic equation calculator. Now I'm not sure if that is the most efficient way of doing it but thought to give it a try. So here is my code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
#include <cmath>

using namespace std;

class QEq {
    float a, b, c, d, D;
public:
    void set_values (float, float, float);
    float areaplus () {return ((-b/(2*a))+(D/(2*a)));}
    float areaminus () {return ((-b/(2*a))-(D/(2*a)));}
    friend QEq find_d (QEq);
};

void QEq::set_values(float A, float B, float C)
{
    a=A;
    b=B;
    c=C;
}

QEq find_d (QEq obj)
{
    QEq ob;
    ob.d=(obj.b*obj.b)-(4*obj.a*obj.c);
    ob.D=sqrt(ob.d);
    return (ob);
}

int main ()
{
    QEq sett;
    QEq findd;
    sett.set_values(1, -3, -4);
    findd=find_d (sett);
    cout << findd.areaplus() << endl;
    cout << findd.areaminus() << endl;
    return 0;
}


My problem here is that when it compiles the result is
-inf
-inf
I also tried using double instead of float but the results are the same. So any help with trying to fix my code would be much appreciated, also other ways of making such a program.

P.S. I know I haven't added "if else" statements, I just thought I could add them later after the main problem is solved.
Last edited on

findd=find_d (sett);

In the find_d function - the values of d and D get set from calculations on values from the Qeq object you pass into the function, but a,b and c don't get set. So when you call the area functions on findd - a, b and c have uninitialized garbage in them.

1
2
cout << findd.areaplus() << endl;
    cout << findd.areaminus() << endl;


If I change the code to call those functions on the original object, it returns these values.
1
2
    cout << sett.areaplus() << endl;
    cout << sett.areaminus() << endl;

0.545507
2.45449



I might look into creating a constructor that at least initializes the variables to a default value. You could also look into creating a copy constructor.

Edit: Here's the tutorial page on classes/constructors from this site
http://www.cplusplus.com/doc/tutorial/classes/
Last edited on
Thank you for your help but I am not sure that I understand everything you have mentioned. If I am correct, simply changing

cout << findd.areaplus() << endl;
cout << findd.areaminus() << endl;

to

cout << sett.areaplus() << endl;
cout << sett.areaminus() << endl;

should make the code compile "0.545507 and 2.45449". Problem is my compiler says "1.45999e+032 and -1.45999e+032". Also the correct answer for this equation should be "4 and -1". And also could you explain a bit more to me on how a constructor that initializes variables works? (specifically in this program if it is possible) and also how a copy constructor could work here? I am sorry if I come out as a total beginner but that is because I am and every help is VERY appreciated!
Also the correct answer for this equation should be "4 and -1".


Ah OK, I called the setvalues function and then the area functions. Since D hadn't been assigned a valid value yet, the result wasn't correct. d and D are only set in the friend function.

I might make the find_d function a void function, passing in a Qeq object by reference, so the function updates d and D without having to create a new QEq object within the function.
1
2
3
4
5
void find_d (QEq & obj)
{
    obj.d=(obj.b*obj.b)-(4*obj.a*obj.c);
    obj.D=sqrt(ob.d);
}



Constructors are unique functions in that they have no return type at all, not even void. A default constructor takes no parameters but can be used to initialize data members to a default value - in this case I would just make sure that a does not get set to 0 (at any time, not just the constructor), to avoid divide by zero errors.

1
2
3
4
Qeq() {
        //default constructor
        //assign default values to the class data members
    }


So when you create an object in main like this, the default constructor is called.
QEq ob;

You can also have a constructor that takes parameters.
1
2
3
4
Qeq(float A, float B, float C) {
        //constructor
        //assign passed in values to the class data members
    }


So when you create an object in main like this, this constructor that takes three float parameters is called.
QEq ob(2.3, 4.5, 6.6);

A copy constructor would allow you to do something like this.

1
2
    QEq ob1;
    QEq ob2(ob1);


It can also be useful to overload the assignment operator so that you can do something like this:

1
2
3
    QEq ob1(2.3, 4.5, 6.6);
    QEq ob2;
    ob2 = ob1;


There's more reading on those here :)
http://www.learncpp.com/cpp-tutorial/911-the-copy-constructor-and-overloading-the-assignment-operator/
Your explanations made it a lot clearer how these work now. I just couldn't fully understand the first part, so, what do I need to change specifically from my original code so I get the right results? And also many thanks for your help!
Here are some of the tweaks I made. I left out the second object for now and just call the functions on one equation.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <cmath>

class QEq {
    float a, b, c, d, D;
public:
    void set_values (float, float, float);
    float areaplus () {return ((-b/(2*a))+(D/(2*a)));}
    float areaminus () {return ((-b/(2*a))-(D/(2*a)));}
    friend void find_d (QEq &);//changed to void and takes object by reference
};

void QEq::set_values(float A, float B, float C)
{
    //could add in check for A equal to 0 here
    a=A;
    b=B;
    c=C;
    //perhaps add in calculations for d and D here so that they update if a,b and c change
}

//changed to void and parameter sent by reference
void find_d (QEq & obj)
{
    obj.d=(obj.b*obj.b)-(4*obj.a*obj.c);
    obj.D=sqrt(obj.d);
}

int main ()
{
    QEq sett;
    sett.set_values(1, -3, -4);
    find_d(sett);
    std::cout << sett.areaplus() << std::endl;
    std::cout << sett.areaminus() << std::endl;
    return 0;
4
-1
Last edited on
So many thanks for your help! (The part I missed last time was putting an "&" after QEq at the prototype of find_d in class QEq.) I will surely study everything you mentioned more to get a better understanding. Thank you again!
Last edited on
You're welcome - glad that helped some.
Topic archived. No new replies allowed.