How would I operate overload "<<"? - c++

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;
}

Related

No match for operator << in exception handling program

#include <iostream>
#include <string>
#include "NegativeBalanceException.hpp"
#include <memory>
class Account
{
private:
std::string name;
double balance;
public:
Account(std::string name, double balance);
~Account() {std::cout <<"Calling Account Destroyer" << std::endl;}
void get_name() const {std::cout << name << std::endl;}
void get_balance() const {std::cout << balance << std::endl;}
friend std::ostream &operator<<(std::ostream &os, const Account &account);
};
Account::Account(std::string name, double balance)
: name{name}, balance{balance} {
if (balance < 0)
throw NegativeBalanceException();
}
std::ostream &operator<<(std::ostream &os, const Account &account) {
os << "Account Name: " << account.get_name() << "\n" << "Account
Balance: " << account.get_balance() << std::endl;
return os;
}
int main () {
std::unique_ptr<Account> Austin;
try {
Austin = std::make_unique<Account>("Austin",1000);
std::cout << *Austin << std::endl;
}
catch (const NegativeBalanceException &ex) {
std::cerr << ex.what() << std::endl;
}
};
Hello I am a beginner programmer and I am practicing exception handling and I do not know why my overloaded operator << is not working. It won't let me display my data that I want.
Your get_name() and get_balance() methods are both declared with void return values, so your overloaded operator<< can't pass them to os << .... Internally, the methods are doing their own logging to std::cout, so you would need to change your operator<< accordingly, eg:
std::ostream &operator<<(std::ostream &os, const Account &account) {
os << "Account Name: ";
account.get_name();
os << "Account Balance: ";
account.get_balance();
return os;
}
However, this will not work as expected if os does not refer to std::cout, for example if your main() decided to stream the Account to a std::ofstream instead.
A better option is to change get_name() and get_balance() to return values instead, and not do their own logging directly:
std::string get_name() const { return name; }
double get_balance() const { return balance; }
Then your overloaded operator<< will work as expected.
These
void get_name() const {std::cout << name << std::endl;}
void get_balance() const {std::cout << balance << std::endl;}
should be written like this
std::string get_name() const { return name; }
double get_balance() const { return balance; }
Functions which return values are not the same as functions which print values. In your overloaded operator<< you need two functions to return the values in the account object, so the operator<< can print them.

No operator "<<" matches these operands - C++

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

Two derived classes derived from the same base class have different results?

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

C++ Array containing base/derived class objects [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
I'm trying to put together an assignment here and got stuck on one point. The question is to create Person class with Student derived class. Then overload both << and >> operators. In the end create checking program to create array of 20 Persons and keep loading either Person or Student. At any point we can print what we have by far - Person output is Name char*/Age int/Parents *char[2], Student output is Name char*/Age int/ID int.
My problem is with the array point - I can't figure out how to implement this and right now I'm stuck with:
Array of pointers to person
We choose if its person/student
istream to get the data
Here is main code part:
#include <iostream>
#include <conio.h>
#include "Header.h"
using namespace std;
int main()
{
char choice;
Person* Tablica[20];
Person* temp;
int i = 0;
while (1)
{
cout << "choices:" << endl;
cout << "(p)erson, (s)tudent, s(h)ow, (e)nd" << endl;
choice = _getch();
if (choice == 'h' || choice == 'H'){
for (int n = 0; n < i; n++){
cout << *Tablica[n] << endl;
}
}
if (choice == 'e' || choice == 'E'){ break; }
if (choice == 'p' || choice == 'P'){
temp = new Person;
cin >> *temp;
Tablica[i] = temp;
cout << *Tablica[i] << endl;
i++;
}
if (choice == 'S' || choice == 's'){
temp = new Student;
cin >> *temp;
Tablica[i] = temp;
cout << *Tablica[i] << endl;
i++;
}
}
system("PAUSE");
return 0;
}
I'm able to load first person/student and then code breaks without error.
So what I'm asking here is, could you look at the code and perhaps point me in the right direction?
Disclaimer: We have to use array, no vectors etc. Yes, conio.h is there as well and it has to stay... Obviously I'm beginner.
Person:
#include <iostream>
class Person
{
public:
Person();
Person(const Person&);
Person(char* n, int a, char* Parent1, char* Parent2);
char* getName();
int getAge();
char* getDad();
char* getMum();
virtual ~Person();
virtual Person operator=(const Person &);
virtual Person operator+(const Person &);
virtual Person operator+=(Person &);
virtual void write(std::ostream&);
virtual void read(std::istream&);
friend std::istream& operator>>(std::istream&, Person &);
friend std::ostream& operator<<(std::ostream&, Person &);
protected:
char* name;
int age;
char* ParentName[2];
};
class Student : public Person
{
public:
Student();
Student(const Student&);
Student(char* name, int age, int id);
virtual ~Student();
int ident();
Student operator=(const Student &);
Student operator+(const Student &);
Student operator+=(Student &);
virtual void write(std::ostream&);
virtual void read(std::istream&);
friend std::istream& operator>>(std::istream&, Student &);
friend std::ostream& operator<<(std::ostream&, Student &);
private:
int ID;
};
Class
#include "Header.h"
Person::Person(){
name = 0;
age = 0;
ParentName[0] = 0;
ParentName[1] = 0;
}
Person::Person(const Person & other)
{
name = other.name;
age = other.age;
ParentName[0] = other.ParentName[0];
ParentName[1] = other.ParentName[1];
}
Person::Person(char* n, int a, char* Parent1, char* Parent2){
name = n;
age = a;
ParentName[0] = Parent1;
ParentName[1] = Parent2;
}
Person::~Person(){}
char* Person::getName(){ return name; }
int Person::getAge(){ return age; }
char* Person::getDad(){ return ParentName[0]; }
char* Person::getMum(){ return ParentName[1]; }
Person Person::operator=(const Person & other){
name = other.name;
age = other.age;
ParentName[0] = other.ParentName[0];
ParentName[1] = other.ParentName[1];
return *this;
}
Person Person::operator+=(Person & other){
int i;
i = strlen(name) + strlen(other.name) + 4;
char * temp = new char[i];
strcpy_s(temp, i, name);
strcat_s(temp, i, " - ");
strcat_s(temp, i, other.name);
name = temp;
Person wynik(name, age, ParentName[0], ParentName[1]);
return wynik;
}
Person Person::operator+(const Person & other){
int i;
i = strlen(name) + strlen(other.name) + 4;
char * temp = new char[i];
strcpy_s(temp, i, name);
strcat_s(temp, i, " - ");
strcat_s(temp, i, other.name);
Person wynik(temp, age, ParentName[0], ParentName[1]);
return *this;
}
void Person::write(std::ostream& os)
{
os << "Osoba: name = " << this->getName() << ", wiek = " << this->getAge() << ", rodzice: " << this->getDad() << ", " << this->getMum();
}
std::ostream& operator<<(std::ostream& os, Person & other){
other.write(os);
return os;
}
void Person::read(std::istream& is)
{
char* name;
name = new char;
std::cout << "name: " << std::endl;
is >> name;
std::cout << "age: " << std::endl;
int age;
is >> age;
std::cout << "dad: " << std::endl;
char* dad;
dad = new char;
is >> dad;
std::cout << "mum: " << std::endl;
char* mum;
mum = new char;
is >> mum;
Person p(name, age, dad, mum);
*this = p;
}
std::istream & operator>>(std::istream & is, Person & os){
os.read(is);
return is;
}
Student::Student() : Person(){}
Student::Student(const Student& student) : Person(student){
ID = student.ID;
}
Student::Student(char* name, int age, int id) : Person(name, age, 0, 0){
ID = id;
}
Student::~Student(){}
Student Student::operator=(const Student & student){
Person::operator=(static_cast<Person const&>(student));
ID = student.ID;
return *this;
}
Student Student::operator+=(Student & student){
Student wynik(*this);
wynik.Person::operator=(wynik.Person::operator+=(student));
return wynik;
}
Student Student::operator+(const Student& student)
{
Person::operator+(static_cast<Person const&>(student));
return *this;
}
void Student::write(std::ostream& os)
{
os << "Student: name = " << this->getName() << ", age = " << this->getAge() << ", legitymacja: " << this->ident() << std::endl;
}
int Student::ident(){ return ID; }
std::ostream& operator<<(std::ostream& os, Student & other){
other.write(os);
return os;
}
void Student::read(std::istream& is)
{
char* name;
name = new char[20];
std::cout << "name: " << std::endl;
is >> name;
std::cout << "age: " << std::endl;
int age;
is >> age;
std::cout << "ID: " << std::endl;
int id;
is >> id;
Student s(name, age, id);
*this = s;
}
std::istream & operator>>(std::istream & is, Student & st){
st.read(is);
return is;
}
Does this compile?
Table[i] = *temp;
Table is an array of pointers to Person
temp is a pointer to Person
You are trying to put an object into an array that holds pointers. Dereferencing *temp gives you an object - you need a pointer to an object, so don't dereference it there. I would expect the compiler to complain about that... does it?
Also, check your second if statement - it says (choice == 'S' || choice == 'p'), which is probably not what you meant. Both if blocks will execute if choice == 'p'...
And in Person::read() you've only allocated a single character for name. That is likely to end badly...

C++ operator overload doesnt work

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)