Two derived classes having same logic derived from same class but different results.
I have a base class named account and two derived classes from account class named savings_account and checking_account. When I make savings_account object, everything works fine, but when i make an object of checking_account class, it also creates an empty object account class. By using overloaded operator <<, cout << checking_account_object, it gives me the balance of checking_account_object. but when i use get_balance method, it gives me the balance of account_object (I created checking_Account_object but automatically created account_object). Similarly works with deposit method, it deposits money in account_object, not in checking_account_object. I have been stuck in this code for 2 days.
Here is my code for account class:
class account
{
protected:
string name;
double balance;
public:
friend ostream & operator << (ostream &out, account &bank);
account(){
name = "unknown";
balance = 0.00;
}
account (const string &person_name, const double &person_balance){
name = person_name;
balance = person_balance;
}
bool deposit(const double &amount){
if(amount <= 0)
return false;
else{
balance += amount;
return true;
}
}
bool withdraw(const double &amount){
if(amount <= 0 )
return false;
else{
balance -= amount;
return true;
}
}
double getbalance(){
return balance;
}
};
ostream & operator << (ostream &out, account &bank){
out << "The back balance of " << bank.name << " is " << bank.balance << endl;
return out;
}
And Here is my code for savings_account:
class savings_account : public account
{
protected:
string name;
double balance;
double int_rate;
public:
savings_account(){
int_rate = 0;
name = "unknown";
balance = 0;
}
savings_account(const string &person_name, const double &person_balance, const double peronal_int_rate){
int_rate = peronal_int_rate;
name = person_name;
balance = person_balance;
}
bool deposit(double amount){
amount += (amount*int_rate)/100;
return account::deposit(amount);
}
friend ostream & operator << (ostream &out, savings_account &bank);
};
ostream & operator << (ostream &out, savings_account &bank){
out << "The bank balance of " << bank.name << " is " << bank.balance << endl;
return out;
}
and Here is checing_account class:
class checking_account : public account{
protected:
string name;
double balance;
const double fee = 1.5;
public:
checking_account(){
name = "unknown";
balance = 0;
}
checking_account(const string &person_name, const double &personal_balance){
name = person_name;
balance = personal_balance;
}
bool withdraw(double amount){
amount = amount + fee;
return account::withdraw(amount);
}
friend ostream & operator << (ostream &out, checking_account &bank);
};
ostream & operator << (ostream &out, checking_account &bank){
out << "The name of account is " << bank.name << " and current balance is " << bank.balance << endl;
return out;
}
main() function:
int main(){
savings_account savings_account("tanzeel", 2000, 2);
savings_account.deposit(1000);
cout << savings_account.getbalance() << endl;
savings_account.withdraw(100);
cout << savings_account.getbalance() << endl;
cout << savings_account;
checking_account checking_account_object("tanzeel", 100.0);
checking_account_object.deposit(50);;
checking_account_object.withdraw(100);
cout << checking_account_object.getbalance() << endl;
cout << checking_account_object;
return 0;
}
Savings_account is working well. But checking_account is not giving me required output.
I expected the output of checking_account_object to be
48.5
The name of account is tanzeel and current balance is 48.5
but the output is
-51.5
The name of account is tanzeel and current balance is 100
Related
My professor said operator overloading of << is optional here but I wanted to know how I could do it as I was only able to figure it out without using overloading.
This is a function in my code:
void listProducts()
{
//list all the available products.
cout << "Available products:\n";
for(int i=0; i<numProducts; i++)
cout << products[i]->getCode() << ": " << products[i]->getName() << " # "
<< products[i]->getPrice() << "/pound.\n";
}
And this is the product.cpp file:
Product :: Product(int code, string name, double price) {
this->code = code;
this->name = name;
this->price = price;
}
int Product:: getCode(){
return code;
}
string Product :: getName(){
return name;
}
double Product :: getPrice(){
return price;
}
You can do something like
std::ostream & operator<<(std::ostream &out,const classname &outval)
{
//output operation like out<<outval.code<<":"<<outval.name<<"#"<<outval.price;
return out;
}
and
friend std::ostream & operator<<(std::ostream &out,const classname &outval);
in your class to access private members.
If you understood the solution to your previous question this, then understanding the below code is very easy. The only difference is the usage of friend function about which you can read gfg link.
For your better understanding, the exact same example is given below,
#include <iostream>
using namespace std;
class Product
{
private:
int code; string name; double price;
public:
Product(int, string, double);
friend ostream & operator << (ostream &out, const Product &p);
};
Product :: Product(int code, string name, double price) {
this->code = code;
this->name = name;
this->price = price;
}
ostream & operator << (ostream &out, const Product &p)
{
out<< p.code << ": " << p.name << " # "
<< p.price << "/pound.\n";
return out;
}
int main()
{
Product book1(1256,"Into to programming", 256.50);
Product book2(1257,"Into to c++", 230.50);
cout<<book1<<endl<<book2;
return 0;
}
I'm fairly new to C++ and starting my main university project. All is going well so far, however I have came across this problem and after hours of searching the web i'm still clueless.
The problem occurs in Portfolio::displayAccounts()when I am trying to loop through a vector to display each element inside the vector.
It will not allow me to use the typical std::cout << which I have always used for things like arrays.
Any Help will be greatly appreciated.
#include <vector>
#include "Account.h"
class Portfolio
{
private:
std::vector<Account> accounts;
public:
double calculateNetWorth();
Portfolio();
void addAccount(std::string name, double balance);
void displayAccounts();
};
#include "Account.h"
double Account::getBalance() {
return balance;
}
Account::Account(std::string name, double balance){
this->name = name;
this->balance = balance;
}
#include <string>
class Account
{
private:
std::string name;
double balance;
public:
double getBalance();
Account(std::string name, double balance);
};
#include <iostream>
#include <string>
double Portfolio::calculateNetWorth() {
double total = 0;
for (auto& account : accounts) {
total += account.getBalance();
}
return total;
}
Portfolio::Portfolio() {
}
void Portfolio::addAccount(std::string name, double balance) {
std::cout << "Account Name: ";
std::cin >> name;
std::cout << "Account Balance: ";
std::cin >> balance;
Account account = Account(name, balance);
accounts.push_back(account);
}
void Portfolio::displayAccounts() {
std::cout << "nThe vector elements after push back are: ";
for (int i = 0; i < accounts.size(); i++) {
std::cout << accounts[i] << " ";
}
}
The standard library has no idea how an instance of your Account class should be outputted. In order to be able to write something like this:
std::cout << some_account;
you need to overload the << operator, for example like this:
class Account
{
private:
std::string name;
double balance;
public:
double getBalance();
Account(std::string name, double balance);
// add this so the overloaded << operator can access your private members
friend std::ostream& operator<<(std::ostream& os, const Account& o);
};
// Implementation
std::ostream& operator<<(std::ostream& os, const Account& a)
{
os << "Name: " << a.name << " Balance: " << a.balance << "\n";
return os;
}
Will print something like this for an Account instance:
Name: SomeName Balance: 123.45678
Bonus:
If you're using C++11 you can write this:
for (auto & account : accounts)
std::cout << account << " ";
instead of:
for (int i = 0; i < accounts.size(); i++) {
std::cout << accounts[i] << " ";
You're trying to print accounts[i] which has the Account type. As your object does not have a << overloaded operator, you won't be able to print anything.
There are 2 solutions :
Overload the << operator
Print rather the name or the balance attributes of your class
I'm getting this error and have searched for a good 4-6 hour to try and get a solution but none of my searches yielded any results in my particular situation so here is my main.cpp.
#include <iostream>
#include <string>
#include "Entrepreneur.h"
#include <fstream>
using namespace std;
bool operator >(const Entrepreneur & Group1,const Entrepreneur & Group2)
{
if((Group1.Points > Group2.Points || Group1.Points == Group2.Points) && Group1.Profit > Group2.Profit )
{
return true;
}
else
{
return false;
};
};
ostream &operator<<( ostream &output,const Entrepreneur &Group1)
{
output <<"\nItem : " << Group1.Item << "\nNr : " << Group1.Nr << "\nDonation : R" << Group1.Donation << "\nStart up amount : R" << Group1.StartUpAmt << "\nExpenses : R" << Group1.Expenses <<"\nPoints : " << Group1.Points << "\nSold : " << Group1.Sold << endl;;
return output;
};
istream &operator>>( istream &input,const Entrepreneur & Group1)
{
cout << "Enter Items to be sold,Donation amount,number of members & startup amount. Seperated by a space." << endl;
input >> Group1.Item >> Group1.Donation >> Group1.Nr >> Group1.StartUpAmt;
return input;
};
int main()
{
return 0;
};
and here is my header file.
#ifndef ENTREPRENEUR_H_INCLUDED
#define ENTREPRENEUR_H_INCLUDED
#include <iostream>
#include <string>
using namespace std;
class Entrepreneur{
private:
string Item;
int Nr;
double Donation;
double StartUpAmt;
double Expenses;
double Income;
double Profit;
int Points;
bool Sold;
public:
Entrepreneur(){
Item = "Not Decided";
Nr = 1;
Donation = 0;
StartUpAmt = 0;
Expenses = 0;
Income = 0;
Profit = 0;
Points = 0;
Sold = 0;
};
void CreatGroup(string iItem,int iNr,double iDonation,double iStartUpAmt){
Item = iItem;
Nr = iNr;
Donation = iDonation;
StartUpAmt = iStartUpAmt;
};
void DisplayGroup(){
cout << "\nItem : " << Item << "\nNr : " << Nr << "\nDonation : R" << Donation << "\nStart up amount : R" << StartUpAmt << "\nExpenses : R" << Expenses << "\nIncome : R" << Income << "\nProfit : R" << Profit << "\nPoints : " << Points << "\nSold : " << Sold << endl;
};
void set_info(double iExpenses,double iIncome,bool iSold){
Expenses = iExpenses;
Income = iIncome;
Sold = iSold;
};
void calc_profit(double iDonation,double iStartUpAmt,double iExpenses,double iIncome){
Donation = iDonation;
StartUpAmt = iStartUpAmt;
Expenses = iExpenses;
Income = iIncome;
Profit = Income + (StartUpAmt + Donation) - Expenses;
};
void update_points(){
Points = 0;
if(Nr < 3)
{
Points ++;
}
else
{
Points + 2;
}
if(Donation == 0)
{
Points ++;
}
if(Sold == 1)
{
Points ++;
}
};
void Display(){
cout << "Congratulations to all groups that partook in the challenge !" << endl;
};
friend bool operator >(const Entrepreneur & Group1,const Entrepreneur & Group2);
friend ostream &operator<<( ostream &output,const Entrepreneur & Group1);
friend istream &operator>>( istream &input,const Entrepreneur & Group1);
};
#endif // ENTREPRENEUR_H_INCLUDED
So the error comes from the friend member that overloads the operator>>
In Entrepreneur class in Entrepreneur.h
friend istream &operator>>( istream &input,const Entrepreneur & Group1);
In main.cpp:
istream &operator>>( istream &input,const Entrepreneur & Group1)
{
cout << "Enter Items to be sold,Donation amount,number of members & startup amount. Seperated by a space." << endl;
input >> Group1.Item >> Group1.Donation >> Group1.Nr >> Group1.StartUpAmt;
return input;
};
I have hit a wall here normally 10min on google and I would have fixed it but this one has got the better of me. PS the program is not finished found this when i started testing.
Thanks in advance.
You are trying to read into a const object
istream &operator>>(istream &input, const Entrepreneur & Group1)
This is why your
input >> Group1.Item >> Group1.Donation >> Group1.Nr >> Group1.StartUpAmt;
does not compile. Get rid of the const in the parameter declaration.
An unrelated issue
Points + 2;
This is no-op statement.
My code compiles fine. But when i try to use my overloaded operator<< - app crashes. I didn't find any decisions by myself.If i don't use this operator everything works just fine. For example, i can pass negative argument to constructor and it will show a message using class data pointer 'company'. Debugger shows that programm crashes at this line:
os << "Company: " << s.company
in function:
std::ostream& operator<<(std::ostream& os, const Stock& s)
{
using std::ios_base;
// set format to #.###
ios_base::fmtflags orig =
os.setf(ios_base::fixed, ios_base::floatfield);
std::streamsize prec = os.precision(3);
os << "Company: " << s.company
<< " Shares: " << s.shares << '\n';
os << " Share Price: $" << s.share_val;
// set format to #.##
os.precision(2);
os << " Total Worth: $" << s.total_val << '\n';
// restore original format
os.setf(orig, ios_base::floatfield);
os.precision(prec);
return os;
}
Here's the code:
// stock20.h -- augmented version
#ifndef STOCK20_H_
#define STOCK20_H_
#include <iostream>
class Stock
{
private:
char* company;
int shares;
double share_val;
double total_val;
void set_tot() { total_val = shares * share_val; }
public:
Stock(); // default constructor
Stock(const char* co, long n = 0, double pr = 0.0);
~Stock(); // do-nothing destructor
void buy(long num, double price);
void sell(long num, double price);
void update(double price);
const Stock & topval(const Stock & s) const;
friend std::ostream& operator<<(std::ostream& os, const Stock& s);
};
#endif
Realisation:
// stock20.cpp -- augmented version
#include "stock20.h"
#include <cstring>
#define my_delete(x){ delete[] x; x = NULL; }
using namespace std;
// constructors
Stock::Stock() // default constructor
{
company = new char[1];
company[0] = '\0';
shares = 0;
share_val = 0.0;
total_val = 0.0;
}
Stock::Stock(const char* co, long n, double pr)
{
company = new char[strlen(co)+1];
strcpy(company,co);
if (n < 0)
{
std::cout << "Number of shares can't be negative; "
<< company << " shares set to 0.\n";
shares = 0;
}
else
shares = n;
share_val = pr;
set_tot();
}
// class destructor
Stock::~Stock() // quiet class destructor
{
my_delete(company);
}
// other methods
void Stock::buy(long num, double price)
{
if (num < 0)
{
std::cout << "Number of shares purchased can't be negative. "
<< "Transaction is aborted.\n";
}
else
{
shares += num;
share_val = price;
set_tot();
}
}
void Stock::sell(long num, double price)
{
using std::cout;
if (num < 0)
{
cout << "Number of shares sold can't be negative. "
<< "Transaction is aborted.\n";
}
else if (num > shares)
{
cout << "You can't sell more than you have! "
<< "Transaction is aborted.\n";
}
else
{
shares -= num;
share_val = price;
set_tot();
}
}
void Stock::update(double price)
{
share_val = price;
set_tot();
}
std::ostream& operator<<(std::ostream& os, const Stock& s)
{
using std::ios_base;
// set format to #.###
ios_base::fmtflags orig =
os.setf(ios_base::fixed, ios_base::floatfield);
std::streamsize prec = os.precision(3);
os << "Company: " << s.company
<< " Shares: " << s.shares << '\n';
os << " Share Price: $" << s.share_val;
// set format to #.##
os.precision(2);
os << " Total Worth: $" << s.total_val << '\n';
// restore original format
os.setf(orig, ios_base::floatfield);
os.precision(prec);
return os;
}
const Stock & Stock::topval(const Stock & s) const
{
if (s.total_val > total_val)
return s;
else
return *this;
}
And the code usage:
// usestok2.cpp -- using the Stock class
// compile with stock20.cpp
#include "stock20.h"
const int STKS = 4;
int main()
{{
//create an array of initialized objects
Stock stocks[STKS] = {
Stock("NanoSmart", 12, 20.0),
Stock("Boffo Objects", 200, 2.0),
Stock("Monolithic Obelisks", 130, 3.25),
Stock("Fleep Enterprises", 60, 6.5)
};
std::cout << "Stock holdings:\n";
int st;
for (st = 0; st < STKS; st++)
std::cout<<stocks[STKS]; //here we got an error
// set pointer to first element
const Stock * top = &stocks[0];
for (st = 1; st < STKS; st++)
top = &top->topval(stocks[st]);
// now top points to the most valuable holding
std::cout << "\nMost valuable holding:\n";
std::cout<<*top;}
// std::cin.get();
return 0;
}
If since i asked 1 question, i hope you don't mind me asking another one. How can i avoid using includes in headers. For example for overloaded operator<< i need to include iostream cause it has return value of ostream& type and a parameter of the same type. Thanks in advance.
When you declare an array:
Stock stocks[STKS] = ...
the array elements are indexed 0 through STKS - 1. When you access stocks[STKS] in this line:
std::cout<<stocks[STKS]; // Out-of-bounds: STKS > STKS - 1
you're accessing a non-existent array element, which is causing the crash. Given the context, you probably want std::cout<<stocks[st]; instead (hat tip: #gx_).
I have a question about operators and how to overload them. There is an example of code and I'm overloading operator<< but it doesn't work. There is class that I use:
class CStudent{ //class for students and their attributes
int m_id;
int m_age;
float m_studyAverage;
public:
CStudent(int initId, int initAge, float initStudyAverage): m_id(initId), m_age(initAge), m_studyAverage(initStudyAverage){}
int changeId(int newId){
m_id = newId;
return m_id;
}
int increaseAge(){
m_age++;
return m_age;
}
float changeStudyAverage(float value){
m_studyAverage += value;
return m_studyAverage;
}
void printDetails(){
cout << m_id << endl;
cout << m_age << endl;
cout << m_studyAverage << endl;
}
friend ostream operator<< (ostream stream, const CStudent student);
};
Overload:
ostream operator<< (ostream stream, const CStudent student){
stream << student.m_id << endl;
stream << student.m_age << endl;
stream << student.m_studyAverage << endl;
return stream;
}
And there is main method:
int main(){
CStudent peter(1564212,20,1.1);
CStudent carl(154624,24,2.6);
cout << "Before the change" << endl;
peter.printDetails();
cout << carl;
peter.increaseAge();
peter.changeStudyAverage(0.3);
carl.changeId(221783);
carl.changeStudyAverage(-1.1);
cout << "After the change" << endl;
peter.printDetails();
cout << carl;
return 0;
}
Where is the problem?
The problem here is you need to learn what references are and the difference between std::ostream and std::ostream& is.
std::ostream& operator<< (std::ostream& stream, const CStudent& student)