0

My program is outputting a strange set of numbers for each customer, and its not getting each customers' names. I'm not sure if I'm using the virtual functions correctly, as this is something relatively new to me conceptually.

The Compute_Bill() function is used in each class, because the Premium_Customer is using a different calculation for their bills than the normal Customer. I have commented out the cost for the calculations for each bill.

The main() function is just for building a list with different names and number of calls for each person, that way the program is supposed to show examples of the two different pricing plans.

Here is the output:

Customer owes 10 dollars.

Customer owes 20.4 dollars.

Customer owes -7.02934e+114 dollars.

Customer owes 20.4 dollars.

Customer owes 10 dollars.

Customer owes 20.4 dollars.

Customer owes 10 dollars.

Customer owes 20.4 dollars.

Customer owes 10 dollars.

Customer owes 20.4 dollars.

Customer owes 10 dollars.

Customer owes 20.4 dollars.

Customer owes 10 dollars.

Customer owes 20.4 dollars.

Customer owes 10 dollars.

Customer owes 20.4 dollars.

Customer owes 10 dollars.

Customer owes 1.24244e+150 dollars.

And here is my program, from top to bottom it starts with Customer class, then Premium Class, and then the main:

#include <iostream> using namespace std; // CUSTOMER CLASS class Customer { private: double numCalls; string name; const double MONTH_FEE = 10; const double PER_CALL = .5; protected: double bill; public: Customer(); Customer(string aName, double aCalls); virtual double Compute_Bill(); string getName(); void setName(string aName); double getCalls(); void setCalls(double aCalls); }; Customer::Customer() { } Customer::Customer(string aName, double aCalls) { aName = ""; aCalls = 0; } string Customer::getName() { return name; } void Customer::setName(string aName) { aName = name; } double Customer::getCalls() { return numCalls; } void Customer::setCalls(double aCalls) { aCalls = numCalls; } // Computing the bill for the Customer, uses // bill = monthlyfee + (percallrate * numcalls) // monthly fee = $10 // per call charge = .50 double Customer::Compute_Bill() { bill = MONTH_FEE + (PER_CALL * numCalls); return bill; } // PREMIUM_CUSTOMER CLASS class Premium_Customer : public Customer { private: double numCalls; string name; const double MONTH_FEE = 20; const double PER_CALL = .05; const double PER_MINUTE = .1; const double NUM_MINS = 4; protected: double bill; public: Premium_Customer(); Premium_Customer(string aName, double aCalls); virtual double Compute_Bill(); string getName(); void setName(string aName); double getCalls(); void setCalls(double aCalls); }; Premium_Customer::Premium_Customer() { } Premium_Customer::Premium_Customer(string aName, double aCalls) { aName = ""; aCalls = 0; } string Premium_Customer::getName() { return name; } void Premium_Customer::setName(string aName) { aName = name; } double Premium_Customer::getCalls() { return numCalls; } void Premium_Customer::setCalls(double aCalls) { aCalls = numCalls; } // Computing the bill for the Premium_Customer, uses // bill = monthlyfee + (percallrate * numcalls) + (permin_callrate * nummins) // monthly fee = $20 // per call charge = .05 // per minute call rate = .10 // nummins = 4 double Premium_Customer::Compute_Bill() { bill = MONTH_FEE + (PER_CALL * numCalls) + (PER_MINUTE * NUM_MINS); return bill; } // MAIN CLASS int main () { Customer* list[18] ; list[0] = new Customer("John Dough", 20); list[1] = new Premium_Customer("Bob Dough", 20); list[2] = new Customer("Tim Dough", 30); list[3] = new Premium_Customer("Jane Dough", 30); list[4] = new Customer("Bill Dough", 40); list[5] = new Premium_Customer("Tom Dough", 40); list[6] = new Customer("Jim Dough", 50); list[7] = new Premium_Customer("Kane Dough", 50); list[8] = new Customer("Hon Dough", 60); list[9] = new Premium_Customer("Jill Dough", 60); list[10] = new Customer("Mary Dough", 70); list[11] = new Premium_Customer("Un Dough", 70); list[12] = new Customer("Sarah Dough", 80); list[13] = new Premium_Customer("Liz Dough", 80); list[14] = new Customer("Will Dough", 90); list[15] = new Premium_Customer("Mike Dough", 90); list[16] = new Customer("Brian Dough", 100); list[17] = new Premium_Customer("Kurt Dough", 100); for(int i=0; i<18; i++) { cout << "Customer " << list[i]->getName() << " owes " << list[i]->Compute_Bill() << " dollars." << endl; } // delete all the customers return 1; } 
10
  • Your constructors do not seem to be setting member variables correctly. And same goes with a lot of your functions. Try passing inputs by const/const& to functions that are supposed to set variables to catch the errors. Commented Sep 27, 2016 at 15:42
  • @RobertPrévost can you explain why they are wrong? Commented Sep 27, 2016 at 15:45
  • Take Customer::Customer(string aName, double aCalls) for instance. Instead of setting the member variables, the temporary input variables are set instead. Commented Sep 27, 2016 at 15:46
  • @RobertPrévost oh! whoops haha. Thank you Robert. Commented Sep 27, 2016 at 15:47
  • @Yoyokolo don't hold currency in floating point types. You'll loose money! Commented Sep 27, 2016 at 15:54

2 Answers 2

1

You had a lot of small mistakes. Your inheritance was basically fine, you just need to remove the parts you don't need:

#include <iostream> #include <string> using namespace std; // CUSTOMER CLASS class Customer { private: double numCalls; string name; const double MONTH_FEE = 10; const double PER_CALL = .5; protected: double bill; public: Customer(); Customer(const string& aName, double aCalls); virtual double Compute_Bill(); string getName() const; void setName(const string& aName); double getCalls() const; void setCalls(double aCalls); }; Customer::Customer() { } Customer::Customer(const string& aName, double aCalls) { setName(aName); setCalls(aCalls); } string Customer::getName() const { return name; } void Customer::setName(const string& aName) { // you had this mixed up name = aName; } double Customer::getCalls() const { return numCalls; } void Customer::setCalls(double aCalls) { // this was mixed up too numCalls = aCalls; } // Computing the bill for the Customer, uses // bill = monthlyfee + (percallrate * numcalls) // monthly fee = $10 // per call charge = .50 double Customer::Compute_Bill() { bill = MONTH_FEE + (PER_CALL * numCalls); return bill; } // PREMIUM_CUSTOMER CLASS class Premium_Customer : public Customer { private: const double MONTH_FEE = 20; const double PER_CALL = .05; const double PER_MINUTE = .1; const double NUM_MINS = 4; public: Premium_Customer(); Premium_Customer(const string& aName, double aCalls); virtual double Compute_Bill(); // the other methods are already inherited, no need to implement them again... }; Premium_Customer::Premium_Customer() { } // no special logic here, just delegate to your base class constructor Premium_Customer::Premium_Customer(const string& aName, double aCalls) : Customer(aName, aCalls) { } // Computing the bill for the Premium_Customer, uses // bill = monthlyfee + (percallrate * numcalls) + (permin_callrate * nummins) // monthly fee = $20 // per call charge = .05 // per minute call rate = .10 // nummins = 4 double Premium_Customer::Compute_Bill() { // no direct access to private customer variables here, used getCalls method instead bill = MONTH_FEE + (PER_CALL * getCalls()) + (PER_MINUTE * NUM_MINS); return bill; } // MAIN CLASS int main() { Customer* list[18]; list[0] = new Customer("John Dough", 20); list[1] = new Premium_Customer("Bob Dough", 20); list[2] = new Customer("Tim Dough", 30); list[3] = new Premium_Customer("Jane Dough", 30); list[4] = new Customer("Bill Dough", 40); list[5] = new Premium_Customer("Tom Dough", 40); list[6] = new Customer("Jim Dough", 50); list[7] = new Premium_Customer("Kane Dough", 50); list[8] = new Customer("Hon Dough", 60); list[9] = new Premium_Customer("Jill Dough", 60); list[10] = new Customer("Mary Dough", 70); list[11] = new Premium_Customer("Un Dough", 70); list[12] = new Customer("Sarah Dough", 80); list[13] = new Premium_Customer("Liz Dough", 80); list[14] = new Customer("Will Dough", 90); list[15] = new Premium_Customer("Mike Dough", 90); list[16] = new Customer("Brian Dough", 100); list[17] = new Premium_Customer("Kurt Dough", 100); for (int i = 0; i<18; i++) { cout << "Customer " << list[i]->getName() << " owes " << list[i]->Compute_Bill() << " dollars." << endl; } // delete all the customers return 0; } 
Sign up to request clarification or add additional context in comments.

1 Comment

I believe you have helped me before. Thank you once again. There's always the little things that get me like that. But I love to learn from my mistakes! Thank you!
0

Your code has Undefined Behavior since your constructors don't initialize the member fields. In particular the member numCalls is never initialized and it is used for the result of the method Compute_Bill.

Tools like valgrind point onto such errors: on your code, valgrind says

by 0x401C55: main (file.cpp:157) Conditional jump or move depends on uninitialised value(s) 

In fact in your methods setCall, your should define

numCalls = aCall; 

and not

aCall = numCalls; 

which has no effect since it does affect a parameter.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.