This is my first time posting here so I'm sorry if there are some formatting rules that I am not following.
I'm having some trouble with my Rational Class program. I think the problem is with my readRational but I'm not sure. The input that i use in this case is 3/4 and then 4/5 but when i output those inputs, I don't get the value that I input.
Another problem is with my constructors. Whenever I declare them i get the error "undefined reference to `rational::rational()'"
class rational
{
public:
// ToDo: Constructor that takes int numerator and int denominator
// ToDo: Constructor that takes int numerator
// ToDo: Default Constructor
// ToDo: Member function to read a rational in the form: n/d
void readRational();
// ToDo: Member function to write a rational as n/d
void printRational();
// ToDo: declare an accessor function to get the numerator
int getNumerator();
// ToDo: declare an accessor function to get the denominator
int getDenominator();
// ToDo: delcare a function called Sum that takes two rational objects
// sets the current object to the sum of the given objects using the
// formula: a/b + c/d = ( a*d + b*c)/(b*d)
int sum(rational, rational, rational);
private:
int numerator;
int denominator;
};
void rational::readRational()
{
int numerator, denominator;
char slash;
// Use this model for your rational class, even though we
// generally don't loop in an input function.
do {
cin >> numerator >> slash >> denominator;
if (slash != '/' || denominator < 0) {
cout << "wrong input." << endl;
cout << "Enter a valid rational: ";
}
} while (slash != '/' || denominator < 0);
int main()
{
// ToDo: declare three rational objects using the default constructor
char answer;
rational op1, op2, op3;
// Main loop to read in rationals and compute the sum
do {
cout << "\nEnter op1 (in the format of p/q): ";
// ToDo: use your input member function to read the first rational
op1.readRational();
op1.printRational();
cout << "\nEnter op2 (in the format of p/q): ";
// ToDo: use your input member function to read the second rational
op2.readRational();
op2.printRational();
// ToDo: use the third rational to call Sum with first and second as parameters
op3.sum(op1, op2, op3);
cout << "\nThe sum of op1 and op2 is: ";
// ToDo: ouptput the third rational
op3.printRational();
cout << endl;
cout << "\nTry again (Y/N)?";
cin >> answer;
} while (answer == 'y' || answer == 'Y');
// ToDo: test getters
cout << "\nC's numerator is: " ;
cout << "\nC's denominator is: ";
// TODO: Use two constructors to declare a whole number 3/1 and a 4/5
1) In your method readRational(): int numerator, denominator;
These local variables shadow your class properties (it means this method does pretty nothing).
2) Your method sum() doesn’t return anything, but it’s declared ‘int’ (which is unclear, btw; shouldn’t it return a rational?)
3) Your class properties are uninitialized.
It means they contains garbage.
Another problem is with my constructors. Whenever I declare them i get the error "undefined reference to `rational::rational()'"
Cannot reproduce your error: I can add any constructor I want.
Example:
What should I return in my sum function? And yeah I realized that it was supposed to be rational instead of int thank you.
The constructors that I used were. I put these in the rational class
1 2 3 4 5 6 7
public:
// ToDo: Constructor that takes int numerator and int denominator
rational(int numerator, int denominator);
// ToDo: Constructor that takes int numerator
rational(int numerator);
// ToDo: Default Constructor
rational();
you can make it pretty with the <> tool on the side-bar editor or [word][/word] tags where word = code
while it is possible to pass in a variable to fill out as the result in a function, you don't see as much of that in object oriented code. Remember to pass by reference as well if you do that. Its best to pass objects by reference anyway, for performance reasons (it avoids a time wasting copy operation).
public:
// ToDo: Constructor that takes int numerator and int denominator
rational(int numerator, int denominator);
// ToDo: Constructor that takes int numerator
rational(int numerator);
// ToDo: Default Constructor
rational();
you do not want to use the same names as the class data members. You "can" but it is messier.
if you have this
class.... etc...
int a; int b;
name::name(int a, int b)
{
a = a; //compiler can't tell which a is which here. this won't do what you want.
this-> a = a; //extra clutter tells it to make the class variable have the input value.
}
_arg is just adding a little something to your variable names to avoid this situation.
he could also have just said num and dem or x and y or whatever. _ is a legal character in a variable name and is often used to split words in some code styles.
he could also have just said num and dem or x and y or whatever
Perfect explanation.
I’ve stolen this charming ‘_arg’ suffix from someone on this forum, I’m quite sure it was mbozzi. I immediately fell in love with it :) and I think it increases code readability a lot.
// ToDo: delcare a function called Sum that takes two rational objects
// sets the current object to the sum of the given objects using the
// formula: a/b + c/d = ( a*d + b*c)/(b*d)
So it it takes two arguments and modifies the current object. I suppose you could return the current object or void, just be sure that you modify the current object.
1 2 3 4 5
Rational sum(Rational a, Rational b)
{
// add a and b, storing the result in this.
return *this;
}