Help with improving my test code

Hello,

I read a C++ tutorial and from there got some code where everything was in main().  I basically broke it apart and for the first time wrote C++ functions.  Now I am looking to improve the transformed code.  Any suggestions for improvements so I can learn from the experts would be much appreciated.  

Thanks in advance!  
meaarAsked:
Who is Participating?
 
NickGeorghiouConnect With a Mentor Commented:
Hi mearr,

The next step would be to start thinking in OO terms i.e. think about coming up with some reusable class or classes. A simple example might be to develop a Loan class.

1. Create a Loan.h and Loan.cpp file.

2. Define your Loan class in the Loan.h file e.g.

class Loan
{
    Loan(double amtOfLoan, double intRate, int years);
    virtual ~Loan();
   
    //... other functions here e.g. ...
    float mortgage();

    //... members here e.g.
    float m_LoanAmt;
    float m_IntRate;
    int    m_Years;

}

3. Implement the functions in the cpp file e.g.

Loan::Loan(double amtOfLoan, double intRate, int years):
m_LoanAmt(amtOfLoan),
m_IntRate (intRate),
m_Years(years)
{
}

etc...

4. Then you can use this class in your main by
   a) include the Loan.h file in main by using   #include Loan.h
   b) create a Loan class e.g. after you get the input you could do
          Loan aLoan(AmtofLoan, IntRate, Years);
   c) then you could call functions on the Loan class e.g. you could put a mortgage function in the loan class and do:

cout << "Returns a monthly mortgage payment of $" << aLoan.mortgage() << " per month." << endl;

       
By using a Loan class this means that you can create an maintain as many loans as you like within the lifetime of the program.

Hope this helps,
Regds,
Nick


 
0
 
meaarAuthor Commented:
Oops I guess I forgot to include my code...  Eeks. :P


#include <math.h>
#include <string>
#include <iostream>
#include <stdlib.h>

using namespace std;


double MonthRate (double IntRate);
double MonthTerm (int Years);


int main()
{
   double AmtofLoan, IntRate;                          
   int Years;                                
   

   cout << "Enter the loan amount in dollars: ";
   cin >> AmtofLoan;
   cout << "Enter the loan term in years: ";
   cin >> Years;
   cout << "Enter the interest rate as a percentage (5.75): ";
   cin >> IntRate;
   cout << endl;  
   cin.get();
   cout << "Loan amount of $" << AmtofLoan << endl;
   cout << "For a term of " << MonthTerm(Years) <<" months" << endl;
   cout << "With an interest rate of " << IntRate<< "%" << endl;
   
   double Mortgage = AmtofLoan * (MonthRate(IntRate) / (1-(pow((1+MonthRate(IntRate)), -MonthTerm(Years)))));
   cout << "Returns a monthly mortgage payment of $" << Mortgage << " per month." << endl;
   cin.get();

}

double MonthRate (double IntRate)
{
 return IntRate / (12 * 100);
}

double MonthTerm (int Years)
{
return Years * 12;
}
0
 
meaarAuthor Commented:
I was initially also trying to create a Mortgage function, but I was having difficulty trying to figure out how to call in the other function variables  and to call the main() functions AmtofLoan variable.  
0
Cloud Class® Course: Microsoft Azure 2017

Azure has a changed a lot since it was originally introduce by adding new services and features. Do you know everything you need to about Azure? This course will teach you about the Azure App Service, monitoring and application insights, DevOps, and Team Services.

 
meaarAuthor Commented:
Awesome.  I'll start working on this.  I am sure I will ask more questions, however.  Hopefully you won't mind me bugging you some more even after I've accepted your answer.  

Cheers!
0
 
NickGeorghiouCommented:
Happy to help.
Ask away :-)
0
 
meaarAuthor Commented:
OK, so I need a good tutorial for the virtual keyword usage. :P  Can you recommend one?  

0
 
NickGeorghiouCommented:
Sorry about that - I didn't need to put that in the example. You probably don't need to use virtual in a simple example like this.

The virtual keyword is used when you want to be able to redefine the function in a derived class. For example if you wanted your application to support different types of loans you might have a base class Loan and a number of derived classes e.g. HomeLoan, PersonalLoan, etc... Each one of the derived loans might redefine the "mortgage" function.

If you want to understand virtual functions and base classes have a look at the following links:

http://msdn2.microsoft.com/en-us/library/0y01k918.aspx
http://msdn2.microsoft.com/en-us/library/wcz57btd.aspx

Regds,
Nick
0
 
meaarAuthor Commented:
Hi Nick,

I'm stuck...  

This is my new header file: (loan.h)

#include <math.h>
#include <string>
#include <iostream>
#include <stdlib.h>

using namespace std;

class Loan
{
      double MonthRate, MonthTerm;
public:
   void setRate (double);
   void setTerm (double);
};


void Loan::setRate (double IntRate)
{
      MonthRate=IntRate / (12 * 100);      
}

void Loan::setTerm (double Years)
{
      MonthTerm=Years * 12;
}

--------------------------------------------------
This is the loan.cpp file (slightly modified from the original)

#include <loan.h>

using namespace std;


int main()
{
   double AmtofLoan, IntRate;                          
   int Years;                                
   

   cout << "Enter the loan amount in dollars: ";
   cin >> AmtofLoan;
   cout << "Enter the loan term in years: ";
   cin >> Years;
   cout << "Enter the interest rate as a percentage (5.75): ";
   cin >> IntRate;
   cout << endl;  
   cin.get();
   cout << "Loan amount of $" << AmtofLoan << endl;
   cout << "For a term of " << MonthTerm(Years) <<" months" << endl;
   cout << "With an interest rate of " << IntRate<< "%" << endl;
   
   double Mortgage = AmtofLoan * (MonthRate(IntRate) / (1-(pow((1+MonthRate(IntRate)), -MonthTerm(Years)))));
   cout << "Returns a monthly mortgage payment of $" << Mortgage << " per month." << endl;
   cin.get();

}
--------------------------------------------------------
I''m still in the process of trying to figure out what to move and where.  Anyway I tried to do a compile and this is the error I'm getting.  Any ideas?  Do you by chance know of a link of a template (.cpp and .h) so I can see the proper structure?

Deleting intermediate files and output files for project 'loan - Win32 Release'.
--------------------Configuration: loan - Win32 Release--------------------
Compiling...
loan.cpp
D:\Mea_Docs\test\loan.cpp(7) : error C2084: function 'int __cdecl main(void)' already has a body
D:\Mea_Docs\test\loan.cpp(21) : error C2065: 'MonthTerm' : undeclared identifier
D:\Mea_Docs\test\loan.cpp(24) : error C2065: 'MonthRate' : undeclared identifier
Error executing cl.exe.

loan.exe - 3 error(s), 0 warning(s)


THANK YOU!







0
 
NickGeorghiouCommented:
Hi mearr,

Sorry I wasn't clearer in my earlier message. It would be better if you had three files. Lets call the first one main.cpp in which the main function is held and then you would have a separate Loan.h and Loan.cpp. The main.cpp would look very similar to what you already have but you need to create a loan object and then use it. See below:

#include <loan.h>

using namespace std;

int main()
{
   double AmtofLoan, IntRate;                          
   int Years;                                
   
   cout << "Enter the loan amount in dollars: ";
   cin >> AmtofLoan;
   cout << "Enter the loan term in years: ";
   cin >> Years;
   cout << "Enter the interest rate as a percentage (5.75): ";
   cin >> IntRate;
   cout << endl;  
   cin.get();

   // Create a loan object here and pass in the
   // the values of Amount, Years, and Rate.
   // Note: this could be done in the Loan constructor
   // but lets keep it simple for now
   Loan myLoan;
   myLoan.setAmount(AmtofLoan);
   myLoan.setTerm(Years);
   myLoan.setRate(IntRate);
   
   // Then use the myLoan object from now on...
   cout << "Loan amount of $" << myLoan.getAmount() << endl;
   cout << "For a term of " << myLoan.getMonthTerm() <<" months" << endl;
   cout << "With an interest rate of " << myLoan.getRate() << "%" << endl;
   
   // We could create a Loan function for Mortgage but lets worry about this later...
   double Mortgage = AmtofLoan * (MonthRate(IntRate) / (1-(pow((1+MonthRate(IntRate)), -MonthTerm(Years)))));
   cout << "Returns a monthly mortgage payment of $" << Mortgage << " per month." << endl;
   cin.get();
}

--------------------------------------------------

Now your Loan.h file is good but lets add some more functions to it as per my mods above so that you can both set values on it, and also retrieve values from it.

#include <math.h>
#include <string>
#include <iostream>
#include <stdlib.h>

using namespace std;

class Loan
{
   double MonthRate
   double Amount;
   int MonthTerm;

public:

   void setAmount(double);
   void setRate (double);
   void setTerm (int); // I have change this to int since Years is int

   // then add some functions to retrieve values of loan
   double getAmount();
   double getRate();
   int getMonthTerm();
 
};


--------------------------------------------------

And finally you should create a separate Loan.cpp file to implement your functions in rather than putting them in your .h file. This would be the functions you already have plus new functions such as getMonthTerm etc... :

void Loan::setRate (double IntRate)
{
     MonthRate=IntRate / (12 * 100);    
}

void Loan::setTerm (double Years)
{
     MonthTerm=Years * 12;
}

int Loan::getMonthTerm()
{
   return MonthTerm;
}


--------------------------------------------------

Try this and see how you go,
Cheers,
Nick


0
 
meaarAuthor Commented:
Thanks Nick!  I will give it a try. :)  This is fun!
0
 
meaarAuthor Commented:
Hello again,

We're making progress!  :)  I had to work through some errors.  For the moment I only have one error left.  Here's what the files look like now.  Please do let me kow if I am changing things which are wrong.  

---------------
main.cpp
---------------
#include <loan.h>

using namespace std;

int main()
{
   double AmtofLoan, IntRate;                          
   int Years;                                
   
   cout << "Enter the loan amount in dollars: ";
   cin >> AmtofLoan;
   cout << "Enter the loan term in years: ";
   cin >> Years;
   cout << "Enter the interest rate as a percentage (5.75): ";
   cin >> IntRate;
   cout << endl;  
   cin.get();

   // Create a loan object here and pass in the
   // the values of Amount, Years, and Rate.
   // Note: this could be done in the Loan constructor
   // but lets keep it simple for now
   Loan myLoan;
   myLoan.setAmount(AmtofLoan);
   myLoan.setTerm(Years);
   myLoan.setRate(IntRate);
   
   // Then use the myLoan object from now on...
   cout << "Loan amount of $" << myLoan.getAmount(AmtofLoan) << endl;
   cout << "For a term of " << myLoan.getMonthTerm(Years) <<" months" << endl;
   cout << "With an interest rate of " << myLoan.getRate(IntRate) << "%" << endl;
   
   // We could create a Loan function for Mortgage but lets worry about this later...
   double Mortgage = AmtofLoan * (myLoan.setRate(IntRate) / (1-(pow((1+myLoan.setRate(IntRate)), -myLoan.setTerm(Years)))));
   cout << "Returns a monthly mortgage payment of $" << Mortgage << " per month." << endl;
   cin.get();
}

-------------------------------------------------------------------------

-------------
loan.h
-------------

#include <math.h>
#include <string>
#include <iostream>
#include <stdlib.h>

using namespace std;

class Loan
{
   double MonthRate;
   double Amount;
   int MonthTerm;

public:

   double setAmount(double);
   double setRate (double);
   int setTerm (int); // I have change this to int since Years is int

   // then add some functions to retrieve values of loan
   double getAmount(double);
   double getRate(double);
   int getMonthTerm(int);
 
};

-------------------------------------------------------------------------

----------------
loan.cpp
----------------
#include <loan.h>

using namespace std;

double Loan::setRate (double IntRate)
{
    MonthRate=IntRate / (12 * 100);
      return MonthRate;
      
}

int Loan::setTerm (int Years)
{
    MonthTerm=Years * 12;
      
      
}

int Loan::getMonthTerm()
{
   return MonthTerm;
}
-------------------------------------------------------

Here's the final error I'm getting:

Deleting intermediate files and output files for project 'main - Win32 Release'.
--------------------Configuration: main - Win32 Release--------------------
Compiling...
main.cpp
D:\Mea_Docs\test\main.cpp(37) : warning C4508: 'main' : function should return a value; 'void' return type assumed
loan.cpp
D:\Mea_Docs\test\loan.cpp(20) : error C2511: 'getMonthTerm' : overloaded member function 'int (void)' not found in 'Loan'
        D:\MEA_DOCS\UOFP\POS440\WEEK2\TEST\INCLUDE\loan.h(9) : see declaration of 'Loan'
Error executing cl.exe.

main.exe - 1 error(s), 1 warning(s)

Any ideas Nick!  Thank you again for all of your help!  I am learning a lot!!!!

0
 
meaarAuthor Commented:
Also, can you recommend a good tutorial for beginners?  I've just been googling and reading what I can find.  

Thanks again Nick!
0
 
NickGeorghiouCommented:
Ok you have one warning and one error.

The warning is because you are not returning anything from your main function. Try putting a return at the end of the main function e.g.:

return 0;


The error is because in your header file you have defined

int getMonthTerm(int);

instead of

int getMonthTerm();

The compiler is showing an error because your header file says that the getMonthTerm requires an int passed into it but your cpp file has defined it without an argument.

Give that a go.
Cheers,
Nick

0
 
meaarAuthor Commented:
Thanks again Nick!  You ROCK!  After I get this going and I totally comprehend what was done I then plan to implement your other suggestions.  Learning is FUN! :)  You deserve another 500 points for all of your help!  I'll let you know how it goes.

Cheers!
0
 
meaarAuthor Commented:
Hello Nick,

I believe I started to make a mess of things so I went back to your originals...  We're getting closer. :)

Here are the errors I'm getting:

Deleting intermediate files and output files for project 'main - Win32 Release'.
--------------------Configuration: main - Win32 Release--------------------
Compiling...
main.cpp
D:\Mea_Docs\test\main.cpp(35) : error C2065: 'MonthRate' : undeclared identifier
D:\Mea_Docs\test\main.cpp(35) : error C2065: 'MonthTerm' : undeclared identifier
loan.cpp
Error executing cl.exe.

main.exe - 2 error(s), 0 warning(s)

------------------------------------------------------------------------------------------------
main.cpp
-------------

#include <loan.h>

using namespace std;

int main()
{
   double AmtofLoan, IntRate;                          
   int Years;  
   
   
   cout << "Enter the loan amount in dollars: ";
   cin >> AmtofLoan;
   cout << "Enter the loan term in years: ";
   cin >> Years;
   cout << "Enter the interest rate as a percentage (5.75): ";
   cin >> IntRate;
   cout << endl;  
   cin.get();

   // Create a loan object here and pass in the
   // the values of Amount, Years, and Rate.
   // Note: this could be done in the Loan constructor
   // but lets keep it simple for now
   Loan myLoan;
   myLoan.setAmount(AmtofLoan);
   myLoan.setTerm(Years);
   myLoan.setRate(IntRate);
     
   // Then use the myLoan object from now on...
   cout << "Loan amount of $" << myLoan.getAmount() << endl;
   cout << "For a term of " << myLoan.getMonthTerm() <<" months" << endl;
   cout << "With an interest rate of " << myLoan.getRate() << "%" << endl;
   
   // We could create a Loan function for Mortgage but lets worry about this later...
   double Mortgage = AmtofLoan * (MonthRate(IntRate) / (1-(pow((1+MonthRate(IntRate)), -MonthTerm(Years)))));
   cout << "Returns a monthly mortgage payment of $" << Mortgage << " per month." << endl;
   cin.get();
   return 0;
}

-------------------------------------------------------------------------------------------------------
loan.h
----------------

#include <math.h>
#include <string>
#include <iostream>
#include <stdlib.h>

using namespace std;

class Loan
{

   double MonthRate;
   //double Amount;    //doesn't appear to be used anywhere
   int MonthTerm;

public:

   void setAmount(double);
   void setRate (double);
   void setTerm (int); // I have change this to int since Years is int

   // then add some functions to retrieve values of loan
   double getAmount();
   double getRate();
   int getMonthTerm();
 
};

------------------------------------------------------------------------------------------------
loan.cpp
----------------

#include <loan.h>

using namespace std;

void Loan::setRate (double IntRate)
{
     MonthRate=IntRate / (12 * 100);    
}

void Loan::setTerm (int Years)
{
     MonthTerm=Years * 12;
}

int Loan::getMonthTerm()
{
   return MonthTerm;
}

0
 
NickGeorghiouCommented:
Hi mearr,

Yes you are correct. You are very close now.
If you look at the error, ithe compiler is telling you that at line 35 it does not know what MonthRate and MonthTerm are because there are no variables of this name that are accessible directly to the main function. To use these variables from the Loan class you need to use the functions on the Loan class in the same way we did it for the cout statements, i.e. in your mortgage equation replace MonthTerm with myLoan.getMonthTerm( ), and replace MonthRate with myLoan.getRate( ).

Btw. you will need to implement the getRate function in your Loan.cpp. It will look very similar to getMonthTerm except that it returns double.

----------

There is an alternative however. You could instead implement a mortgage function within the Loan class, i.e. have a function called getMortgage( ).  I will leave that for you to try later...


Let me know how you go,
Regds,
Nick

0
 
meaarAuthor Commented:
Thanks Nick.  I'm playing with it and I think I almost got it. ;)
0
 
meaarAuthor Commented:
This is a odd looking error, would you happen to know what it is telling me?  I'm googling so maybe I'll be able to find something online.  

main.obj : error LNK2001: unresolved external symbol "public: double __thiscall Loan::getRate(double)" (?getRate@Loan@@QAENN@Z)
main.obj : error LNK2001: unresolved external symbol "public: double __thiscall Loan::getAmount(double)" (?getAmount@Loan@@QAENN@Z)
main.obj : error LNK2001: unresolved external symbol "public: double __thiscall Loan::setAmount(double)" (?setAmount@Loan@@QAENN@Z)

I'll keep going until I get it... :)
0
 
NickGeorghiouCommented:
Hi meaar,

The reason you are getting these errors is because the linker cannot find the implementation of the functions getRate, getAmount, and setAmount. These are specified in Loan.h but you have not implemented them yet in Loan.cpp .  You can either implement them in Loan.cpp if you require to use them in your main function otherwise you can remove them (or comment them out) from the Loan.h file.

Cheers,
Nick

0
 
meaarAuthor Commented:
GOT IT!  NO errors. :)  The math is wrong, but I'll fix that.  

THANK YOU SO MUCH Nick!  I decided to start to learn C++ and you are helping me do that.  I really appreicate this site and all of the experts that contribute!  This site is worth a lot more then what I pay monthly.  It is so nice to be able to get advice and direction.  There may be hope for me yet?!

Cheers!

0
 
NickGeorghiouCommented:
Great stuff mearr. Congratulations.

btw... I just searched through some of the previous questions to see what tutorials were recommended for others. I haven't used any myself. I learnt the old fashioned way from a book. The following one seems pretty good:

http://www.warebizprogramming.com/tutorials/cpp/toc.htm

Cheers,
Nick
0
 
meaarAuthor Commented:
I'll be sure to read this.  Thanks again Nick!
0
 
meaarAuthor Commented:
OK, so I have one more question... :)

When I run the program (which compiled without errors :) I get below.  I'm not seeing why the loan amount and the mortgage amount is wrong.
---------------------------------------------------
Enter the loan amount in dollars: 5000000
Enter the loan term in years: 30
Enter the interest rate as a percentage (5.75): 6.0

Loan amount of $1.85319e-307
For a term of 360 months
With an interest rate of 6%
Returns a monthly mortgage payment of $1.11108e-309 per month.

------------------------------------------------------

Here's my code

--------------------
main.cpp
--------------------
#include <loan.h>

using namespace std;

int main()
{
   double AmtofLoan, IntRate;                          
   int Years;  
   
   
   cout << "Enter the loan amount in dollars: ";
   cin >> AmtofLoan;
   cout << "Enter the loan term in years: ";
   cin >> Years;
   cout << "Enter the interest rate as a percentage (5.75): ";
   cin >> IntRate;
   cout << endl;  
   cin.get();

   // Create a loan object here and pass in the
   // the values of Amount, Years, and Rate.
   // Note: this could be done in the Loan constructor
   // but lets keep it simple for now
   Loan myLoan;
   myLoan.Amount(AmtofLoan);
   myLoan.setTerm(Years);
   myLoan.setRate(IntRate);
   
     
   // Then use the myLoan object from now on...
   cout << "Loan amount of $" << myLoan.Amount(AmtofLoan) << endl;
   cout << "For a term of " << myLoan.getTerm(Years) <<" months" << endl;
   cout << "With an interest rate of " << IntRate << "%" << endl;
   
   // We could create a Loan function for Mortgage but lets worry about this later...
   //double Mortgage = myLoan.Amount(AmtofLoan) * (myLoan.getRate(IntRate) / (1-(pow((1+myLoan.getRate(IntRate)), -myLoan.getTerm(Years)))));
   cout << "Returns a monthly mortgage payment of $" << myLoan.Mortgage() << " per month." << endl;
   cin.get();
   return 0;
}

----------------
loan.h
---------------
#include <math.h>
#include <string>
#include <iostream>
#include <stdlib.h>

using namespace std;

class Loan
{
public:
   
   double MonthRate, MonthAmount, MortgagePay;
   int MonthTerm;
   
   double Amount(double),setRate (double), getRate(double), Mortgage(void);
   int setTerm (int), getTerm(int);
};


-------------
loan.cpp
---------------

#include <loan.h>

using namespace std;

double Loan::setRate (double IntRate)
{
     MonthRate=IntRate / (12 * 100);
     return MonthRate;
}

int Loan::setTerm (int Years)
{
     MonthTerm=Years * 12;
       return MonthTerm;
}


int Loan::getTerm(int)
{
   return MonthTerm;
}

double Loan::getRate(double)
{
   return MonthRate;
}

double Loan::Amount(double AmtofLoan)
{
   return MonthAmount;
}

double Loan::Mortgage(void)
{
   MortgagePay = MonthAmount* MonthRate/ (1-(pow((1+MonthRate), -MonthTerm)));
   return MortgagePay;
}


Any ideas Nick?
0
 
meaarAuthor Commented:
Never mind Nick.  I figured it out.  I forgot a part:

// Function to get the MonthAmount
double Loan::Amount(double AmtofLoan)
{
   MonthAmount=AmtofLoan;
   return MonthAmount;
}
0
 
NickGeorghiouCommented:
Hi meaar,

If you look at the output you will so that the Loan amount is incorrect:

Loan amount of $1.85319e-307

This points to the error. The error is that the loan amount is not saved on the loan object.
In your Loan::Amount function you should set the MonthAmount member to the value passed in i.e.

double Loan::Amount(double AmtofLoan)
{
   MonthAmount = AmtofLoan;
   return MonthAmount;
}


This should fix your problem.  However you should be careful here because you have one function that does the set and get. I noticed that you bunched up all your functions in the header file and that your are passing arguments to the get functions. Technically speaking this is not required, e.g. the following would work:

double getAmount(), getRate(), Mortgage();
void setAmount (double), setRate(double);

int getTerm();
void setTerm(int);

Cheers,
Nick
0
 
meaarAuthor Commented:
Thanks Nick.  Can you recommend a link that helps explain the style for setter and getter functions?  

Thanks again!
0
 
NickGeorghiouCommented:
Hi mearr,

My advice here was not really a question of style (because you will find many differences of opinion here). But rather a question of design.

The simple answer is when you design a function, only provide it what it needs.

For example, you had the following in your Loan.cpp

int Loan::getTerm(int)
{
   return MonthTerm;
}

Here you are passing an argument to the getTerm function which does not get used. And therefore is not necessary.

----------------

Next example,

double Loan::Amount(double AmtofLoan)
{
   MonthAmount = AmtofLoan;
   return MonthAmount;
}


In this example you are actually changing the loan amount every time you are getting it. In fact all you are doing is retrieving the same value that you have passed into the function anyway. If however, the Amount function used the input to manipulate some other value, and then return it, then this would make more sense. For example a function like:

double Loan::increaseLoan(double AmtofExtraLoan)
{
   MonthAmount += AmtofExtraLoan;
   return MonthAmount;
}


Hope this makes sense,
Regds,
Nick



0
 
meaarAuthor Commented:
That makes perfect sense.  Thanks again Nice! :)
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.