variable is undefined, yet clearly defined in my constructor C++ - c++

I have a C++ assignment that requires me to create a class called Tips, that:
has a single member variable, float taxRate
has two constructors, a default that sets taxRate to .65, and a one parameter constructor, that sets taxRate to whatever float the user enters in my tipMain.cpp file.
has only one function, computeTip, that accepts two arguments: totBill and tipRate, both floats that must calculate the before-tax meal cost, and return the tip based on that value and the desired tip rate.
My issue occurs when I attempt to use taxRate inside the computeTip function.
If I use taxRate, computeTip doesn't understand the value of taxRate, stating it is undefined, and even if I do specify tips::taxRate, before I even compile Visual Studio states
Error: a nonstatic member reference must be relative to a specific object.
I vaguely understand this error, but even if I declare taxRate to be static in my .h file, I get LNK2019 errors.
Tips.cpp
#include <iostream>
#include <float.h>
#include "Tips.h"
using namespace std;
Tips::Tips()
{
taxRate = 0.65;
}
Tips::Tips(float a)
{
taxRate = a;
}
float computeTip(float totBill, float tipRate)
{
float mealOnly = 0;
mealOnly = (totBill/taxRate); //written both ways to show errors. taxRate undefined here.
mealOnly = (totBill/Tips::taxRate); //Error: a nonstatic member reference must be relative to a specific object
return (mealOnly * tipRate);
}
Tips.h
#ifndef Tips_H
#define Tips_H
#include <float.h>
using namespace std;
class Tips
{
public:
Tips();
Tips(float);
float computeTip(float, float, float);
float taxRate;
};
#endif
and my tipMain.cpp
#include "Tips.h"
#include <iostream>
#include <iomanip>
using namespace std;
float tax;
float meal;
float tip;
void tipProcessor();
int main()
{
char entry;
int toggle = 1;
cout << "Welcome to the Gratuity Calculator!" << endl;
cout << endl;
while (toggle != 0)
{
cout << "Enter 1 to calculate tip." << endl;
cout << endl;
cout << "Enter 2 to exit." << endl;
cout << endl;
cout << "Entry: ";
cin >> entry;
switch (entry)
{
case '1':
tipProcessor();
break;
case '2':
toggle = 0;
break;
default:
cout << "Enter 1 or 2." << endl;
cout << endl;
break;
}
}
system("pause");
return 0;
}
void tipProcessor()
{
cout << "Enter bill total: ";
cin >> meal;
cout << endl;
cout << "Enter tax rate: ";
cin >> tax;
cout << endl;
Tips thisTip(tax);
cout << "Enter tip percent: ";
cin >> tip;
cout << endl;
cout << "Tip is $" << setprecision(4) << thisTip.computeTip(meal, tip, thisTip.taxRate) << "." << endl;
cout << endl;
}

You use
float computeTip(float totBill, float tipRate)
But it should be:
float Tips::computeTip(float totBill, float tipRate)
in the implementation. Also you should hide your data members.

You are defining computeTip() as global function, therefore only public static member access is possible. Define as float Tips::computeTip(float ...) and it should compile.

You've not specified that computeTip is a method of Tips. Change it to this:
float Tips::computeTip(float totBill, float tipRate)
{
float mealOnly = 0;
mealOnly = (totBill/taxRate);
return (mealOnly * tipRate);
}
And all should be well.

Your method declaration and and method definition do not have the same signature. In your header file you indicate that computeTip should take 3 float arguments, but when you define it in the .cpp file, it only takes two arguments.
This is in addition to what other users suggest, prefixing your function with Tips:: to indicate that it is part of the Tips class and thus should be able to access member variables such as taxRate.
Thus your header declaration should look like:
float computeTips(float, float);
And your method definition should look like
float Tips::computeTip(float totBill, float tipRate)
{
...

Related

While loop in Math::getGradeTotal(string continuegrade) gives error

So essentially what I'm trying to do here is have the user put in their grade information and then in a specific function ask if them if they would like to continue putting in grades. When I try this however I get an error with the while loop so I'm not quite sure what I'm doing wrong. I have provided all the code so that you guys can get a better understanding of what I'm trying to do. I get the error at "Math::getGradeTotal(string continuegrade)" and it says in the compiler
These are the errors they're spitting out in the compiler
Line 23: error: prototype for 'int Math::getGradeTotal()(std::_cxxll::string)' does not math any in class
Line 23: error: candidate is std::_cxxll::string Math::getGradeTotal()
#include <iostream>
#include <string>
#include "Math.h"
using namespace std;
string student_name;
double test_grade;
int main()
{
string continuegrade;
double gradeinput;
char courseinput;
cout << "Please enter students name: " << endl;
cin >> student_name;
cout << "Please select what course you would like to enter grades (1-
Math, 2-Science): "<< endl;
cin >> courseinput;
cout << "Please insert grade:" << endl;
cin >> gradeinput;
Math Student1(gradeinput, continuegrade);
if (courseinput == '1')
{
cout << "Grade put in:" << Student1.getGrade() << endl;
Student1.getGradeTotal();
}
if (courseinput == '2')
{
cout << "**You have selected Science**" << endl;
}
return 0;
}
Header File
#include <iostream>
#include <string>
using namespace std;
#ifndef MATH_H
#define MATH_H
class Math
{
public:
//default constructor
Math();
//overload constructor
Math(double , string);
//destructor
~Math();
//accessor functions
double getGrade();
//getGrade - gets the input of the grade
string getGradeTotal();
//getGradeTotal - takes the input and adds onto itself
private:
//Member variables
double new_gradeinput;
string new_continuegrade;
};
#endif // MATH_H
.CPP Source File
#include "Math.h"
Math::Math()
{
new_gradeinput = 0.0;
//ctor
};
Math::Math(double gradeinput, string continuegrade)
{
new_gradeinput = gradeinput;
//new_continuegrade = continuegrade;
};
Math::~Math()
{
};
double Math::getGrade()
{
return new_gradeinput;
}
Math::getGradeTotal(string continuegrade)
{
new_continuegrade = continuegrade;
while ((new_continuegrade == 'Y') || (new_continuegrade == 'y'))
{
cout << "Would you like to continue" << endl;
cin >> new_continuegrade;
}
/*cout << "Grade total: " << new_gradeinput << endl;
return new_gradeinput;*/
}
I know this is kind of long but any and all help will be greatly appreciated.

C++: 1-What is a different between define a variable to keep and print the answer ,2-and just print the answer?

What is the difference between :
#define PI 3.14
using namespace std;
int main()
{
int r;
float area;
cout << "Enter the radius:";
cin>>r;
area=r*r*PI;
cout << area << endl;
}
and
#define PI 3.14
using namespace std;
int main()
{
int r;
cout << "Enter the radius:";
cin>>r;
cout << r*r*PI <<endl;
}
The answer is in your case it changes nothing.
You can always use godbolt to take a look at the asm.
https://godbolt.org/z/wkFHM5
As you can see
area=r*r*PI;
cout << area << endl;
produces the same code as
cout << r*r*PI << endl;
The intermediate variable is a way and storing data that you want to reuse that is all.

How to call user defined functions in C++?

Below you will find my dismal attempt to create a user defined function. I am trying to do an assignment that calculates the area and cost of installing carpet for various shapes. I am also suppose to keep a running total of them. In addition the assignment requires that I use a used defined function. Right now all it does is accept the input of 1 and ask "What is the length of the side: ". It then loops back to the selection menu. It does not calculate a total much less keep track of the total. What am I doing wrong in creating the user defined function and how can I incorporate it to keep a running total till they exit?
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <cmath>
using namespace std;
void square(double);
const double UNIT_PRICE = 2.59;
const double LABOR_COST = 32.5;
const double PIE = 3.14;
const double TAX = .0825;
int main() {
int selection;
int sqrSide = 0;
// declare and initialize the variables for the shape
int sqrTot = 0;
do {
// get input from user as to what they want to do
cout << "Carpet Area Shape" << endl;
cout << "1. Square" << endl;
cout << "2. Rectangle" << endl;
cout << "3. Circle" << endl;
cout << "4. Triangle" << endl;
cout << "5. Done" << endl;
cout << "Type a number to continue: ";
cin >> selection;
cout << endl;
// loop through the solutions based on the user's selection
switch (selection) {
case 1:
cout << "What is the length of the side: ";
cin >> sqrSide;
square(sqrSide);
if (sqrTot > 0) {
cout << "Shape: Square" << endl;
cout << "Side: " << sqrSide << endl;
cout << "Area: " << sqrTot << endl;
}
cout << endl;
system("pause");
break;
case 2:
case 3:
case 4:
case 5: // exit
system("cls");
break;
default:
"You have made an invalid selection. Please choose a number from the "
"list.";
cout << endl;
}
// loop through if the user is still making a valid selection
} while (selection != 5);
system("pause");
return 0;
}
void square(double) {
double sqrSide = 0;
double sqrTot = 0;
double sqrArea;
sqrArea = sqrSide * 4;
// get the total area and store it as a variable
sqrTot += sqrArea;
if (sqrTot > 0) {
cout << "Shape: Square" << endl;
cout << "Side: " << sqrSide << endl;
cout << "Area: " << sqrTot << endl;
}
}
When you declare the prototype of the function you can omit the parameter but in the implementation you must place it.
change:
void square(double)
{
double sqrSide = 0;
double sqrTot = 0;
double sqrArea;
sqrArea = sqrSide * 4;
//get the total area and store it as a variable
sqrTot += sqrArea;
if (sqrTot > 0) {
cout << "Shape: Square" << endl;
cout << "Side: " << sqrSide << endl;
cout << "Area: " << sqrTot << endl;
}
}
to:
void square(double sqrSide)
{
double sqrTot = 0;
double sqrArea;
sqrArea = sqrSide * 4;
//get the total area and store it as a variable
sqrTot += sqrArea;
if (sqrTot > 0) {
cout << "Shape: Square" << endl;
cout << "Side: " << sqrSide << endl;
cout << "Area: " << sqrTot << endl;
}
}
and also change:
case 1:
cout << "What is the length of the side: ";
cin >> sqrSide;
square(sqrSide);
if (sqrTot > 0) {
cout << "Shape: Square" << endl;
cout << "Side: " << sqrSide << endl;
cout << "Area: " << sqrTot << endl;
}
cout << endl;
system("pause");
break;
to:
case 1:
cout << "What is the length of the side: ";
cin >> sqrSide;
square(sqrSide);
system("pause");
break;
As mentioned by πάνταῥεῖ in a comment, it seems that you've a few misconceptions regarding scope of variables, about parameters and about return values. Let's see if we can't dispel some of those.
First of all, lets talk about scope. When we declare a variable inside a block delimited with { and }, the variable only exists inside that block. Code that follows the block cannot access the variable.
So, this is okay:
int a = 3;
int b = 2;
int c = a*b;
But, this is not, since the values of a and b are no longer available:
{
int a = 3;
int b = 2;
}
int c = a*b;
Next, lets talk about parameters. These are the inputs to functions which the function will use in order to complete its task. While their name is irrelevant and essentially meaningless, it will certainly help you and others of you give them meaningful names. Some programming languages and indeed, students of some disciplines don't follow this maxim and can produce code that's harder to follow than it need be. The implementation of Basic found in 20 year old Texas Instruments calculators and physicists, I'm looking at you!
Consider the following functions, (whose bodies I've ommitted for brevity):
double calcArea(double a)
{
...
}
double calcArea(double b)
{
...
}
They both suck. What's a stand for, how about b?
A far better pair might resemble:
double calcArea(double radius)
{
...
}
double calcArea(double sideLenOfSquare)
{
...
}
Lastly, lets talk about return values. In each of the 4 preceding functions, the declaration begins with double. This means that we can expect to get back a value of type double from the function. However, this is just coding - there's no magic and as such, we need to actually let the compiler know what this value will be. Extending the two previous functions, we might come up with some something like the following:
double calcArea(double radius)
{
return 3.1415926535 * (radius * radius);
}
double calcArea(double sideLenOfSquare)
{
return sideLenOfSquare * sideLenOfSquare;
}
Now as it turns out - even these two simple functions are not all they've cracked-up to be. Namely, the first function uses a constant - π (Pi or 3.141....) This already exists (and with far better precision than I've used) in the math.h header file. If this file is included, we then have access to the #defined constant, M_PI.
Next, both of these functions have the same name and take the same number of parameters of identical type. The compiler can't possibly know which one you'd like to invoke. At a minimum, they should have different names. Perhaps something like calcCircleArea and calcSquareArea. Now, the compiler knows which function you're referring to and will happily compile this part of the code. Errors may exist elsewhere, but these are a different matter.
A little research on function overloading will provide resources that can explain the problem and solution to functions with the same name far better than I am both able and inclined to try. :)

initialize class functions but output still 0

I am having problems with this program. When I compile it, I intialize all of the variables based upon the users input, but the cout still shows that the problem has '0' for most of the statements and for one of the statements its a '-negative' number. Any thoughts?
#include <iostream>
#include <conio.h>
#include <cmath>
#include <stdexcept>
using namespace std;
class MortgageCalc
{
protected:
float term;
public:
void setData(float, float, float);
float setTerm ();
float monthly;
float total;
float interest;
int years;
float loan;
};
void MortgageCalc::setData(float l, float i, float y)
{
loan = l;
interest = i;
years = y;
setTerm();
}
float MortgageCalc::setTerm()
{ //simple interest calculation with power calc to establish whole number translation
term = pow((1 + ((interest/100) / 12)), (12 * years));
return term;
}
class mPayment : public MortgageCalc
{
public:
int monthly()
{
return ((loan * ((interest/100) / 12) * term ) / (term - 1));
}
};
class tPayment : public mPayment
{
public:
int total()
{
return (monthly() * (years * 12));
}
};
class iPayment : public tPayment
{
public:
int plusInterest()
{
return (total() - loan);
}
};
int main()
{
double loan(0), interest(0);
int years = 0;
MortgageCalc mort1;
cout << "Enter the total loan amount on your mortgage loan: $"; //established loan variable
cin >> loan;
cout << "Enter the interest rate (in whole #'s only): "; //establishes interest rate variable
cin >> interest;
cout << "Enter the length of the loan in years: "; //establishes term of payments
cin >> years;
mort1.setData(loan, interest, years);
mPayment m;
cout << "Monthly payment due is " << m.monthly() << "." << endl;
tPayment t;
cout << "Total payment will be " << t.total() << "." << endl;
iPayment i;
cout << "Total payment plus Interest will be " << i.plusInterest() << "." << endl;
return 0;
};
You are taking all different objects like MortgageCalc mort1; mPayment m; tPayment t; iPayment i;.
These object do not have any relation.
Example:
mort1 = {term, monthly, total, interest, years, loan}
and suppose you have initialize with 1
mort1 = {term=1, monthly=1, total=1, interest=1, years=1, loan=1}
but it doesnot impact to the m because both are stored in memory on different location.
m = {term=0, monthly=0, total=0, interest=0, years=0, loan=0}
You can check both have different base address like cout<<&mort1<<endl<<&m; .
Data member you have set is part of MortgageCalc mort1 instead of mPayment m; tPayment t;.
You need to brush up your C++ basic's.
You use default constructors on those lines:
mPayment m;
tPayment t;
iPayment i;
They have no notion of previously input data held in mort1. You did not take care for any way to "share" or "communicate" this data.
m,t,i were all initialized with random data. There is no relation to mort1.
I won't go into details of what correct architecture here would be, but you should read about base class initialization. As a hint I'd say in your (a little weird) example you could try making this syntax work:
mPayment m(mort1);

Object is initializing to unwanted value

I have been working on a trivial assignment to get used to coding. I am designing an ATM machine and at the moment it is composed of 2 classes:
BankAccount.cpp
Constructor for different types of account
Only has balance as a member
Transaction.cpp
Performs a method on the BankAccount (i.e make deposit, make withdrawl & get balance)
Problem: BankAccount is automatically initialized to a balance of 10 which is undesired. So for example, if I made a checking account and chose to deposit $10, balance would print out $20.
//BankAccount.h
//This class will simply take in a bank account
//with a balance, other classes will use a bank account object
//such as saving/checkings and perform operations on the
//balance
#ifndef BANK_ACCOUNT_H
#define BANK_ACCOUNT_H
class BankAccount {
private:
float balance;
public:
BankAccount ();
float getBalance ();
void makeDeposit ();
void makeWithdrawl ();
};
#endif
//BankAccount.cpp
#include "BankAccount.h"
#include <iostream> //remove once done *not to self
using namespace std; //remove once done *note to self
BankAccount::BankAccount() {
balance = 0.00;
}
float BankAccount::getBalance() {
return balance;
}
void BankAccount::makeDeposit() {
cout << "How much would you like to deposit: ";
float deposit_value;
cin >> deposit_value;
balance += deposit_value;
}
void BankAccount::makeWithdrawl() {
cout << "How much would you like to withdrawl: ";
float withdrawl_value;
cin >> withdrawl_value;
balance -= withdrawl_value;
}
//Transaction.h
#ifndef TRANSACTION_H
#define TRANSACTION_H
class Transaction {
private:
BankAccount m_bao;
public:
Transaction(BankAccount&);
void displayOptions();
void printReciept();
};
#endif
//Transaction.cpp
#include "BankAccount.h"
#include "Transaction.h"
#include <iostream>
using namespace std;
Transaction::Transaction(BankAccount& bao) {
m_bao = bao;
}
void Transaction::displayOptions() {
cout << "\nPlease make a choice\n\n";
cout << "1: Make Deposit\n";
cout << "2: Make Withdrawl\n";
cout << "3: Check Balance\n";
int choice;
cin >> choice;
switch (choice) {
case 1:
m_bao.makeDeposit();
break;
case 2:
m_bao.makeWithdrawl();
break;
case 3:
m_bao.getBalance();
break;
}
}
void Transaction::printReciept() {
cout << "Current balance is now: " << m_bao.getBalance() + '\n';
}
int main () {
BankAccount checking;
Transaction q(checking);
q.displayOptions();
q.printReciept();
}
I am sure the answer is right in front of my eyes, but my brain is just fried right now. I will continue to look for the solutions and let you guys know if my problem has been solved yet.
[EDIT]
Alright, now I am trying to make it so that the customer can choose to perform transactions on either Checking or Savings account. Currently I got it looking like this in my main():
int main () {
BankAccount checking(0.00);
BankAccount savings(0.00);
Transaction c(checking);
Transaction s(savings);
for(int i = 0; i < 10 ; i++) {
cout << "Make an option" << endl;
cout << "1. Checking " << endl;
cout << "2. Savings" << endl;
int choice;
cin >> choice;
if (choice == 1) {
c.prompt();
c.printReciept();
}
else {
s.prompt();
s.printReciept();
}
}
}
It works fine, but I would like to make this process more OOP-alized, if that makes sense :)
One option I was trying to look into was making a prompt function which would belong to Transaction.cpp. This would do everything that is done in main, except initializing the objects of course.
Your problem is this line:
cout << "Current balance is now: " << m_bao.getBalance() + '\n';
Which the compiler sees as:
cout << "Current balance is now: " << (m_bao.getBalance() + '\n');
'\n' is 10 as an int, so you get this:
cout << "Current balance is now: " << (m_bao.getBalance() + 10);
You probably meant to do this:
cout << "Current balance is now: " << m_bao.getBalance() << '\n';
Remember that in C++, + almost always means "add these two numbers".