0

So, in class for work we have to write a header class for quadratic expression. I have the header file done for the most part, however, when I proceed to run with the given .cpp file to test out the header file, it does not appear to read the values given in the array in the cpp file. When I debug, it just puts in garbage values for the values. To me I thought it made sense and can't see anything wrong with it. Unless am I missing something?

I constructed the following header file...

#pragma once
#include <cmath>

enum roots {
    NO_ROOTS = 0,
    ONE_ROOT = 1,
    TWO_ROOTS = 2,
    INFINITE_ROOTS = 3
};

class quadraticExpression
{
private:
    double a, b, c;
public:

    double evaluate(double x) const;

    int getNumberOfRoots() const;

    double getFirstRoot() const;

    double getSecondRoot() const;

    double getACoefficient() const;

    double getBCoefficient() const;

    double getCCoefficient() const;

    quadraticExpression();

    quadraticExpression(double a,
                        double b,
                        double c);

};

quadraticExpression::quadraticExpression()
{
    a = 0;
    b = 0;
    c = 0;
}
inline quadraticExpression::quadraticExpression(double a, double b, double 
                                                c)
{
    a = a;
    b = b;
    c = c;
}
;

double quadraticExpression::evaluate(double x) const
{
    double y;
    y = (a*(x * x)) + (b * x) + c;
    return y;
}

int quadraticExpression::getNumberOfRoots() const
{
    //return value from enum
    double eins;
    double zwei;
    eins = getFirstRoot();
    zwei = getSecondRoot();


    if (eins == 0 && zwei == 0)
    {
        return TWO_ROOTS;
    }
    else if (eins == 0 || zwei == 0)
    {
        return ONE_ROOT;
    }
    else if (eins != 0 && zwei != 0)
    {
        return NO_ROOTS;
    }

}
double quadraticExpression::getFirstRoot() const
{
    //return one x value where y is 0
    double root1 = (b * b);
    double root2 = (4 * a*c);
    double solutionOne;
    double zUno;
    zUno = (abs(b) + sqrt(root1 - root2)) / (2 * a);
    solutionOne = (a*(zUno * zUno)) + (b * zUno) + c;
    return solutionOne;
}
double quadraticExpression::getSecondRoot() const
{
    //return another x value where y is 0
    double root1 = (b * b);
    double root2 = (4 * a*c);
    double solutionTwo;
    double zDos;
    zDos = (abs(b) - sqrt(root1 - root2)) / (2 * a);
    solutionTwo = (a*(zDos *zDos)) + (b *zDos) + c;
    return solutionTwo;
}

double quadraticExpression::getACoefficient() const
{
    return a;
}

double quadraticExpression::getBCoefficient() const
{
    return b;
}

double quadraticExpression::getCCoefficient() const
{
    return c;
}

And here is the .cpp tester file

#include <iostream>
#include "QuadraticExpression.h"

using namespace std;

void evaluateExpression(const quadraticExpression &);

int main()
{
    quadraticExpression q[6] = { quadraticExpression(2.1, 3, -7),
                                 quadraticExpression(1.4, 3.9, +7),
                                 quadraticExpression(-.75, 0, 0),
                                 quadraticExpression(0, .3, -7),
                                 quadraticExpression(0, 0, 4),
                                 quadraticExpression() };
    for (int i = 0; i<6; i++)
        evaluateExpression(q[i]);

    return EXIT_SUCCESS;
}

void evaluateExpression(const quadraticExpression &q)
{
    int errorsHandled = 0;

    cout << q.getACoefficient() << " A " << endl;
    cout << q.getBCoefficient() << " B " << endl;
    cout << q.getCCoefficient() << " C " << endl;

    cout << "f(-5) = " << q.evaluate(-5) << endl;
    cout << "f(0)  = " << q.evaluate(0) << endl;
    cout << "f(5)  = " << q.evaluate(5) << endl;

    if (q.getNumberOfRoots() == INFINITE_ROOTS)
        cout << "The Expression has Infinite Roots" << endl;
    else if (q.getNumberOfRoots() == ONE_ROOT)
        cout << "The Expression has One Root at x = " << q.getFirstRoot() << 
            endl;
    else if (q.getNumberOfRoots() == TWO_ROOTS)
    {
        cout << "The Expression has First Root at x  = " << q.getFirstRoot() << 
            endl;
        cout << "The Expression has Second Root at x = " << q.getSecondRoot() << 
            endl;
    }
    else
        cout << "The Expression has No Roots" << endl;

    try {
        q.getFirstRoot();
    }
    catch (domain_error e) {
        errorsHandled++;
    }

    try {
        q.getSecondRoot();
    }
    catch (domain_error e) {
        errorsHandled++;
    }

    cout << "Errors Handled: " << errorsHandled << endl;

    cout << endl;
    cout << endl;
}

I fathom I might not be properly acquiring the data values a, b, and c from the array given in the cpp file therefore it just collects garbage values, however I'm stumped here.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • 1
    Welcome to Stack Overflow. Please take a look at our introductory [help pages](https://stackoverflow.com/help), with special attention to the page on [minimal complete examples](https://stackoverflow.com/help/mcve). Most of the code you posted is irrelevant to the problem, and paring it down to the essential doesn't just make our job easier, it makes the bug much easier for *you* to see. It is a vital coding skill. – Beta Jan 27 '18 at 00:56
  • in `quadraticExpression::quadraticExpression(double a, double b, double c)` you have `a = a;` ... that wont work! Although you can use `this->a = a;` it's best to name the member variable and parameter differently. – drescherjm Jan 27 '18 at 00:58
  • @drescherjm I'm not sure which Ayn Rand joke I should make here. – user4581301 Jan 27 '18 at 01:17

1 Answers1

1

This won't work as you intend.

inline quadraticExpression::quadraticExpression(double a, double b, double c)
{
    a = a;
    b = b;
    c = c;
}

You're just assigning the parameter variables to themselves, not assigning to the member variables of the class. Variables declared in a function take precedence over member variables with the same name.

You should give the parameters different names from the member variables, or assign like this->a = a;.

But if you're just initializing member variables from parameters, you don't need to do assignments at all, initializer lists are preferred (see C++: Where to initialize variables in constructor):

quadraticExpression::quadraticExpression(double a, double b, double c) : a(a), b(b), c(c) 
{}

Similarly, the constructor with no arguments should use an initializer list:

quadraticExpression::quadraticExpression() : a(0), b(0), c(0) 
{}
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • See, what you pointed out as it won't work as intended solved an unresolved external error, according to the compiler I'm working with, visual studio 2015, that has to be added in there but it's not clear to me why. I thought that this made sense because I would need a constructor which had given variables that allows for user input. But I think I understand by what you mean by assigning the member variables instead of parameter variables. That fixed the problem of the compiler picking up garbage data – victiminvesta Jan 27 '18 at 23:18
  • I had typos in the member function names, maybe that was the problem. This syntax has been around for a long time, VS2015 should support it. – Barmar Jan 28 '18 at 03:10