"No viable overloaded '=' " why? - c++

I'm making a project for one of my classes and I'm pretty sure I'm almost done with the project. Basically I have to input 2 people's tickets and I have to find the maximum and minimum price. I need to overload the * and / operators to fix that issue for the project. Also, the friend declaration is a necessity for this project via teacher's instructions.
Now, for the issue. I'm trying to store the proper ticket variable (either t1 or t2) into t3 so I can return that to the main. When I use "=" to set either t1 to t3, it says "no viable overloaded '='". The following is my code:
#include <iostream>
using namespace std;
class ticket
{
public:
ticket();
double input();
double output();
friend ticket operator *(const ticket &t1, const ticket &t2);
friend ticket operator /(const ticket &t1, const ticket &t2);
private:
void cost();
string name;
double miles, price;
int transfers;
};
int main()
{
ticket customer1, customer2, customer3;
//------------------------------------------------
cout << "*** Customer 1 ***" << endl;
customer1.input();
cout << "--- Entered, thank you ---" << endl;
cout << "*** Customer 2 ***" << endl;
customer2.input();
cout << "--- Enter, thank you ---" << endl;
//------------------------------------------------
//------------------------------------------------
cout << "Testing of the * operator: " << endl;
customer3 = customer1 * customer2;
cout << "*** Database printout: ***" << endl;
customer3.output();
cout << endl;
cout << "--- End of Database ---" << endl;
//------------------------------------------------
//------------------------------------------------
cout << "Testing of the / operator:" << endl;
customer3 = customer1 / customer2;
cout << "*** Database printout: ***" << endl;
customer3.output();
cout << endl;
cout << "--- End of Database ---" << endl;
//------------------------------------------------
return 0;
}
ticket operator *(const ticket &t1, const ticket &t2)
{
ticket t3;
if (t1.price > t2.price)
t3 = t1.price;
else
t3 = t2.price;
return t3;
}
ticket operator /(const ticket &t1, const ticket &t2)
{
ticket t3;
if (t1.price < t2.price)
t3 = t1.price;
else
t3 = t2.price;
return t3;
}
ticket::ticket()
{
}
double ticket::input()
{
cout << "Miles? ";
cin >> miles;
cout << endl << "Transers? ";
cin >> transfers;
cout << endl << "Name? ";
cin >> name;
cost();
cout << endl << "Price is: " << price << endl;
return miles;
}
double ticket::output()
{
cout << name << '\t' << miles << "mi \t " << transfers << " transfers \t" << price;
return miles;
}
void ticket::cost()
{
price = (.5 * miles) - (50 * transfers);
}

You don't define an operator= for ticket that takes a double as its argument. As a consequence you can't assign doubles to ticket objects.

This is how I get the same compile error. I have mark one of my getter function as const while I still want to modify class member variable. See the following simple example:
class CPath {
private:
std::string m_extension;
public:
std::string GetExtension() const {
if (m_extension.length()==0) {
m_extension = "txt";
}
return m_extension;
}
}
In this case, we have two solutions:
1) drop const modifier in the function definition;
2) mark the property m_extension as mutable.

you might want to have member function
set_price(const& double price)
so you can change the error code like this,which would be better
if (t1.price > t2.price)
t3.set_price(t1.price);
else
t3.set_price(t2.price);

Related

Implementing a non-member IO operator

In my assignment I was asked to create the Product class, and I have finished all the implementations except the "non-member IO operator". The question I found it very vague, it asks me to overload the << and >> operators to work with ostream and istream to read a Product from and print a Product to the console in order to make this main function work.
Here I see the main function has cout or cin to Product's derived class SItem, I wonder how I should implement the << >> operators to make the main work.
My main:
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include "Product.h"
#include <fstream>
#ifdef TAB
# undef TAB
#endif
#define TAB '\t'
using namespace std;
namespace sict {
class SItem :public Product {
public:
SItem(const char* theSku, const char * theName) :Product(theSku, theName) {}
SItem() {}
virtual std::fstream& store(std::fstream& file, bool addNewLine = true)const {
if (!isEmpty()) {
file.open("ms4.txt", ios::out | ios::app);
file << sku() << TAB << name() << TAB << quantity() << TAB << qtyNeeded() << TAB
<< int(taxed()) << TAB << price() << endl;
file.clear();
file.close();
}
return file;
}
virtual std::fstream& load(std::fstream& file) {
file.open("ms4.txt", ios::in);
char buf[2000];
double dbuf;
int ibuf;
file >> buf;
sku(buf);
file >> buf;
name(buf);
file >> ibuf;
quantity(ibuf);
file >> ibuf;
qtyNeeded(ibuf);
file >> ibuf;
taxed(ibuf != 0);
file >> dbuf;
price(dbuf);
file.clear();
file.close();
return file;
}
virtual std::ostream& write(std::ostream& os, bool linear)const {
return isEmpty() ? os : (os << sku() << ": " << name() << ", qty: "
<< quantity() << ", qtyNeeded:" << qtyNeeded()
<< ", Cost: " << fixed << setprecision(2) << cost());
}
virtual std::istream& read(std::istream& is) {
char buf[2000];
double dbuf;
int ibuf;
cout << "Sku: ";
is >> buf;
sku(buf);
cout << "Name (no spaces): ";
is >> buf;
name(buf);
cout << "Qty: ";
is >> ibuf;
quantity(ibuf);
cout << "Qty Needed: ";
is >> ibuf;
qtyNeeded(ibuf);
cout << "Is taxed? (1/0): ";
is >> ibuf;
taxed(ibuf != 0);
cout << "Price: ";
is >> dbuf;
price(dbuf);
return is;
}
};
}
void dumpFile(fstream& f) {
f.open("ms4.txt", ios::in);
char ch;
while (!f.get(ch).fail()) {
cout.put(ch);
}
f.clear();
f.close();
}
using namespace sict;
void test() {
double res, val = 0.0;
fstream F("ms4.txt", ios::out);
F.close();
SItem S;
SItem T;
SItem U;
cout << "Enter Product info: " << endl;
cin >> S;
SItem V = S;
S.store(F);
T.load(F);
cout << "T: (store, load)" << endl;
cout << T << endl;
cout << "S: " << endl;
cout << S << endl;
cout << "V(S): " << endl;
cout << V << endl;
cout << "U=T & op= :" << endl;
U = T;
cout << U << endl;
cout << "Operator == :" << endl;
cout << "op== is " << (T == "1234" ? "OK" : "NOT OK") << endl;
cout << "op+=: " << endl;
U += 10;
cout << U << endl;
cout << "op+=double : " << endl;
res = val += U;
cout << res << "=" << val << endl;
}
int main() {
fstream F("ms4.txt", ios::out);
F.close();
SItem S;
SItem U("4321", "Rice");
cout << "Empty Prouduct:" << endl << S << endl;
cout << "U(\"4321\", \"Rice\"):" << endl << U << endl;
cout << "Please enter the following information:" << endl;
cout << "Sku: 1234" << endl;
cout << "Name(no spaces) : Blanket" << endl;
cout << "Qty : 12" << endl;
cout << "Qty Needed : 23" << endl;
cout << "Is taxed ? (1 / 0) : 1" << endl;
cout << "Price : 12.34" << endl;
test();
cout << "Please enter the following information:" << endl;
cout << "Sku: 1234" << endl;
cout << "Name(no spaces) : Jacket" << endl;
cout << "Qty : 12" << endl;
cout << "Qty Needed : 23" << endl;
cout << "Is taxed ? (1 / 0) : 0" << endl;
cout << "Price : 12.34" << endl;
test();
dumpFile(F);
cout << "----The End" << endl;
return 0;
}
This is my Product.h:
namespace sict {
class Product : public Streamable {
char sku_[MAX_SKU_LEN + 1];
char * name_;
double price_;
bool taxed_;
int quantity_;
int qtyNeeded_;
public:
Product();
Product(const char*, const char*, bool = true, double = 0, int = 0);
Product(const Product&);
virtual ~Product();
Product& operator=(const Product&);
//setters
void sku(const char*);
void price(double);
void name(const char*);
void taxed(bool);
void quantity(int);
void qtyNeeded(int);
//getters
const char* sku()const;
double price()const;
const char* name()const ;
bool taxed()const;
int quantity()const;
int qtyNeeded()const;
double cost()const;
bool isEmpty()const;
//member operators
bool operator==(const char*);
int operator+=(int);
int operator-=(int);
};
double operator+=(double, const Product&);
std::ostream& operator<<(std::ostream& ostr, const Product& p);
std::istream& operator >> (std::istream& istr, Product& p);
}
All the functions have been implemented except the last two, which are the IO operators.
Streamable class is an abstract class that has no implementations.
You did this wrong in many ways.
Best approach in your case is do it like that.
First define interfaces for stream operations, for your products:
class IStreamPrintable
{
public:
virtual std::ostream& PrintToStream(std::ostream& outStream) const = 0;
};
class IStreamReadable
{
public:
virtual std::istream& ReadFromStream(std::istream& inputStream) = 0;
};
Secondly define stream operators which will use this interfaces.
std::ostream& operator<<(std::ostream& out, const IStreamPrintable& printObject)
{
return printObject.PrintToStream(out);
}
std::istream& operator>>(std::istream& input, IStreamReadable& readObject)
{
return printObject.ReadFromStream(input);
}
Now you Product can inherit this interfaces:
class Product
: public IStreamPrintable
, public IStreamReadable
{
…
};
You do not have to implement it immediately. You can implement those methods in specific product classes SItem and it will work out of the box.
Your method virtual std::fstream& store(std::fstream& file, bool addNewLine = true) is total mess. You are passing fstream object and opening some specific file on it. This is wrong since you are unable to write multiple objects to single file. Keep there ostream object and do not change is state (do only writing), so you could cascade calls and so you could avoid hard-coding a file name.

Data from a static vector left unchanged when I leave the method

This is a Bank project I had in mind while learning C++ and I
have been adding to it as I learned inheritance and pointers. The
user is a bank teller who can create a new customer or process
transactions of an existing customer.
A Customer has Savings and Checking classes as private fields that inherit
from Account. The Bank class adds/gets customers from its private static vector<Customer> field.
The unexpected result is that in the 'process_transaction' method I can fetch
a customer from vector and deposit/withdrawl from it's accounts, but once I leave the method and come back to it the accounts data hasn't changed from the time I initialized them.
Need help. It's a reference to customer issue? When should I return by
reference or pointer?
Here is the code. In the driver class I have a method to create a customer
/*
* Create customer from teller input then add the Customer
* to Bank's private static vector<Customer> field.
*/
int create_customer(){
cout << "** Create New Customer **\n";
cout << "Customer Name: ";
string n = "";
cin >> n;
Customer* d = new Customer(n, gen_acct_number());
Customer c(*d);
// get opening balances
double open_ck = 0;
double open_sv = 0;
cout << "Opening Balance For Checking: ";
cin >> open_ck;
cout << "Opening Balance For Savings: ";
cin >> open_sv;
cout << "\n";
// create and set accounts
Checking ck(open_ck);
Savings sv(open_sv);
c.set_checking(ck);
c.set_savings(sv);
// add customer to bank
Bank b;
b.add_customer(c);
cout << "New Customer: " << c.get_name() << endl;
cout << "Account Number: " << c.get_acct_number() << endl;
cout << "\n";
return 0;
}
I have another method in the driver class to process a customer. Once I
leave this method a customer's accounts are unchanged, but works otherwise.
/*
* Fetch customer by account number from Bank's private static
* vector<Customer> and perform transactions on Customer's accounts
* until teller has finished processing the customer.
*/
int process_customer(){
cout << "** Process Transaction **\n";
cout << "Account Number: ";
int acctNum = 0;
cin >> acctNum;
cout << "\n";
// get customer
Bank b;
Customer c = b.get_customer(acctNum);
//if(c* == NULL){
// cout << "Error: Customer Not Found.\n";
// return 0;
//}
bool flag = true;
while(flag){
cout << c.get_name() << " #" << c.get_acct_number() << ": ";
cout << "Select a transaction.\n";
cout << "1. Withdrawl\n";
cout << "2. Deposit\n";
cout << "3. Check Balance\n";
cout << "4. Quit\n";
cout << "> ";
int choice = 0;
cin >> choice;
cout << "\n";
double amt = 0;
int which = 0;
switch(choice){
case 1:{ // WITHDRAWL
cout << "Withdrawl From: \n";
cout << "1. Checking \n2. Savings \n";
cout << "> ";
cin >> which;
cout << "\n";
cout << "Amount: ";
cin >> amt;
cout << "\n";
if(which == 1){
cout << "Old Balance: " << c.get_checking().get_balance() << endl;
c.get_checking().withdrawl(amt);
cout << "New Balance: " << c.get_checking().get_balance() << endl;
cout << "\n";
}else if (which == 2){
cout << "Old Balance: " << c.get_savings().get_balance() << endl;
c.get_savings().withdrawl(amt);
cout << "New Balance: " << c.get_savings().get_balance() << endl;
cout << "\n";
}else{
break;
}
break;
}
case 2:{ // DEPOSIT
cout << "Deposit Into: \n";
cout << "1. Checking \n2. Savings \n";
cout << "> ";
cin >> which;
cout << "\n";
cout << "Amount: ";
cin >> amt;
cout << "\n";
if(which == 1){
cout << "Old Balance: " << c.get_checking().get_balance() << endl;
c.get_checking().deposit(amt);
cout << "New Balance: " << c.get_checking().get_balance() << endl;
cout << "\n";
}else if (which == 2){
cout << "Old Balance: " << c.get_savings().get_balance() << endl;
c.get_savings().deposit(amt);
cout << "New Balance: " << c.get_savings().get_balance() << endl;
cout << "\n";
}else{
break;
}
break;
}
case 3:{ // CHECK BALANCE
cout << "Checking " << c.get_checking().get_balance() << endl;
cout << "Savings " << c.get_savings().get_balance() << endl;
cout << "\n";
break;
}
default:{ // EXIT
flag = false;
break;
}
}
}
return 0;
}
The Bank class.
Bank::Bank(){}
Customer& Bank::get_customer(int acct_number) {
for(unsigned i = 0; i < cus.size(); i++){
if(cus[i].get_acct_number() == acct_number){
return cus[i];
}
}
return cus[0];
}
void Bank::add_customer(Customer c){
cus.push_back(c);
}
/* Disabled. I want to pass an account to these methods.
*
* void Bank::deposit(double amt, Account& a){
* a.deposit(amt);
* }
* void Bank::withdrawl(double amt, Account& a){
* a.withdrawl(amt);
* }
* double Bank::check_balance( Account& a){
* return a.get_balance();
* }
*/
vector<Customer> Bank::cus;
Bank.h
#ifndef BANK_H_
#define BANK_H_
#include "../include/Customer.h"
#include <string>
#include <vector>
using namespace std;
class Bank{
public:
Bank();
Customer& get_customer(int acct_number);
void add_customer(Customer c);
void deposit(double amt, Account& a);
void withdrawl(double amt, Account& a);
double check_balance( Account& a);
private:
static vector<Customer> cus;
};
#endif /* BANK_H_ */
It does indeed appear to be a reference issue. In your process_customer function, change:
// get customer
Bank b;
Customer c = b.get_customer(acctNum);
to:
// get customer
Bank b;
Customer& c = b.get_customer(acctNum);
Without this change, you're making a copy of the customer and then modify this copy, instead of modifying the original customer.

Arithmetic and Relational Operators

I followed my book to the T and for some reason when I try and run my program I get completely wrong output for the operator- and the operator+ for my output. Do you know what is going wrong with my Overloaded operator- and my overloaded operator+. The program compiles fine but the output is not right at all.
#include <iostream>
using namespace std;
class NumDays
{
private:
int ptrHours;
public:
NumDays(int H)// to set the pointer
{ setHours(H);}
void setHours(int H)
{ptrHours = H;}
int gethours() {return ptrHours;}
double calcDays()// function to calculate the days
{
double days;
days = ptrHours/8.0;
return days;
}
friend NumDays operator+(NumDays a, NumDays b);
friend NumDays operator-(NumDays a, NumDays b);
};
NumDays operator+(NumDays a, NumDays b)
{
return NumDays(a.ptrHours + b.ptrHours);
}
NumDays operator-(NumDays a, NumDays b)
{
return (a.ptrHours - b.ptrHours);
}
int main ()
{
NumDays first(0),
second(0),
third(0);
int hours1, hours2;
cout <<"Enter the how many hours you worked..." << endl;
cout <<"First set: ";
cin >> hours1;
while (hours1 < 0)
{
cout <<"\nYou cannot enter a negative value. " << endl;;
cin >> hours1;
}
first.setHours(hours1);
cout <<"Second Set: ";
cin >> hours2;
while (hours1 < 0)
{
cout <<"\nYou cannot enter a negative value. " << endl;;
cin >> hours2;
}
second.setHours(hours2);
cout <<"First set for days worked is " << first.calcDays() <<" days." << endl;
cout <<"Second set for days worked is " << second.calcDays() <<" days." << endl;
third = first - second;// where I try and do my arithmetic operators
cout <<"First - Second = " << cout << third.gethours() << endl;
third = first + second;
cout <<"First + Second = " << cout << third.gethours() << endl;
cin.ignore();
cin.get();
return 0;
}
The problem is in your code.
cout <<"First + Second = " << cout << third.gethours() << endl;
You shouldn't use cout inside a cout. Your print statement should be like this
cout <<"First + Second = " << third.gethours() << endl;
Hope this will help.
Thank you.

c++ Using a second constructor

Hi guys I am trying to do my homework and I've been stuck with some constructors. I am supposed to do this:
Write a program that uses a class named MovieData to store the
following information about a movie:
Title, Director, Year Released, Running Time (in minutes).
Include a constructor that allows all four of these member data
values to be specified at the time a MovieData variable is created.
The program should create two MovieData variables.
Have a method that displays the information about the movie in a clearly formatted manner.
Now include two additional attributes that hold the movie's production costs and first-year revenues.
Add a second constructor so that all six member values can be
specified when a MovieData variable is created.
Copy the method that displays the movie data to create a second method that displays the title, director, release year, running time, and first year's profit or loss.
So far I have this done:
// ch7movie
// By Kevin Mok
#include <iostream>
#include <string>
using namespace std;
class MovieData
{
public:
string title;
string director;
int yearReleased;
int runningTime;
double productionCost;
double firstYearRevenue;
MovieData(string titl, string dir, int yr, int rT, double pC, double fyR); // constructor
};
//Defining constructor
MovieData::MovieData(string titl, string dir, int yr, int rT, double pC, double fyR)
{
title = titl;
director = dir;
yearReleased = yr;
runningTime = rT;
productionCost = pC;
firstYearRevenue = fyR;
}
//Function of movie info
void displayMovieInfo(MovieData movieName)
{
cout << "----------------------------" << endl;
cout << "Title: " << movieName.title << endl;
cout << "Director: " << movieName.director << endl;
cout << "Year Released: " << movieName.yearReleased << endl;
cout << "Running Time: " << movieName.runningTime << " minutes" << endl;
cout << "Production Cost: $" << movieName.productionCost << endl;
cout << "First Year's Profit': $" << movieName.firstYearRevenue - movieName.productionCost << endl;
cout << "----------------------------\n" << endl;
}
int main()
{
MovieData movie1("C++ in English", "JohnCna", 2010, 120, 36500, 50000);
MovieData movie2("Great Programmer", "RKO", 2013, 130, 36500, 100000);
displayMovieInfo(movie1);
displayMovieInfo(movie2);
return 0;
}
I know that I don't have my second constructor, and this is my problem. I have no idea how to declare it; I've been reading my book, but I am having a lot of trouble, because it does not say anything about it. It'd be great if you someone could guide me a little bit
You already have one constructor. Simply do the exact same thing with the other constructor, just with different parameters, like the requirements say to.
And you need to change your displayMovieInfo() standalone function into a method of the class, like the requirements say to.
Try this:
// ch7movie
// By Kevin Mok
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
class MovieData
{
public:
string title;
string director;
int yearReleased;
int runningTime;
double productionCost;
double firstYearRevenue;
// constructors
MovieData(string titl, string dir, int yr, int rT);
MovieData(string titl, string dir, int yr, int rT, double pC, double fyR);
void displayMovieInfo();
void displayMovieInfoAndCosts();
};
//Defining constructors
MovieData::MovieData(string titl, string dir, int yr, int rT)
{
title = titl;
director = dir;
yearReleased = yr;
runningTime = rT;
productionCost = 0.0;
firstYearRevenue = 0.0;
}
MovieData::MovieData(string titl, string dir, int yr, int rT, double pC, double fyR)
{
title = titl;
director = dir;
yearReleased = yr;
runningTime = rT;
productionCost = pC;
firstYearRevenue = fyR;
}
//Methods to display movie info
void MovieData::displayMovieInfo()
{
cout << "----------------------------" << endl;
cout << "Title: " << title << endl;
cout << "Director: " << director << endl;
cout << "Year Released: " << yearReleased << endl;
cout << "Running Time: " << runningTime << " minutes" << endl;
cout << "----------------------------\n" << endl;
}
void MovieData::displayMovieInfoAndCosts()
{
cout << "----------------------------" << endl;
cout << "Title: " << title << endl;
cout << "Director: " << director << endl;
cout << "Year Released: " << yearReleased << endl;
cout << "Running Time: " << runningTime << " minutes" << endl;
cout << "Production Cost: $" << setprecision(2) << productionCost << endl;
cout << "First Year's Profit': $" << setprecision(2) << firstYearRevenue - productionCost << endl;
cout << "----------------------------\n" << endl;
}
int main()
{
MovieData movie1("C++ in English", "JohnCna", 2010, 120, 36500, 50000);
MovieData movie2("Great Programmer", "RKO", 2013, 130, 36500, 100000);
movie1.displayMovieInfo();
movie1.displayMovieInfoAndCosts();
movie2.displayMovieInfo();
movie2.displayMovieInfoAndCosts();
return 0;
}

error C2601: "Name": local function definitions are illegal

I'm new to C++ and learning about Inheritance and Polymorphism. We require to write an employee project that have 4 types of employee (BasePlusCommission, CommisisonEmployee, Salaried and TipWorker). My project has one main() class that I used switch method for each type of employee. I got stuck on TipWorker where we have to do Polymorphism. Here what I got so far.
int main()
{
void virtualViaPointer(const Employee * const);
{
cout << "Enter First Name: " << endl;
cin >> firstName;
cout << "Enter Last Name: " << endl;
cin >> lastName;
cout << "Enter SSN: " << endl;
cin >> SSN;
if (SSN.length() == 9)
{
SSN = true;
}
else
{
cout << "Please enter SSN again with 9 digits only:" << endl;
cin >> SSN;
}
cout << "Enter wages: " << endl;
cin >> wage;
cout << "Enter hours: " << endl;
cin >> hours;
cout << "Enter tips: " << endl;
cin >> tips;
TipWorker employee4(firstName, lastName, SSN, wage, hours, tips);
employee4.print();
cout << fixed << setprecision(2);
vector < Employee * > employees(1);
employees[0] = &employee4;
cout << "Employee processed polymorphically via dynamic binding: \n\n";
cout << "Virtual function calls made off base-class pointers:\n\n";
for (const Employee *employeePtr : employees)
virtualViaPointer(employeePtr);
void virtualViaPointer(const Employee * const baseClassPtr)
{
baseClassPtr->print();
cout << "\nEarned $" << baseClassPtr->earnings() << "\n\n";
}
break;
}
}
When I run the project, I came up with this error:
error C2601: "virtualViaPointer": local function definitions are
illegal
void virtualViaPointer(const Employee * const baseClassPtr)
{
baseClassPtr->print();
cout << "\nEarned $" << baseClassPtr->earnings() << "\n\n";
}
Can anyone please help me? Thank you so much!
You may not define one function inside an other function. Any function definition shall be outside any other function definition.
Place the definition of virtualViaPointer outside the body of main.
You can have a declaration of a function inside a function, but no definition(!) of that function. However, you can have a local struct/class or lambda in the function:
#include <iostream>
void f()
{
void print(); // mostly useless - maybe a most vexing parse error
struct Print {
static void apply(const char* s) { std::cout << s << '\n'; }
}
Print::apply("Hello");
auto lambda = [] (const char* s) { std::cout << s << '\n'; };
lambda("World");
}
Note: A local struct does not require C++11 (Also, it may look nicer while debugging)