How to call a friend operator overload function? - c++

class Sale
{
void Display();
I can call it in another file, let say register.cpp file as
something.Display();
How can I call Display() if were a friend operator<< function?
class Sale
{
friend ostream& operator<<(ostream& os, const Song& s);
here is sale.cpp with ostream definition
ostream& operator<<(ostream & os, const Song& s)
{ //title, artist, category, and size are private member data of sale.h
os << s.title << "\t" << s.artist
<< "\t" << s.category << "\t" << s.size;
}
Display() definition is hard-coded to cout
My assignment also requires me to call the operator<< in register.cpp file
to do the same thing as Display()
How can I do it?

Related

C++ override operator<< in inherited class

I have a base class where the overriding of an << operator is made.
friend std::ostream& operator<<(std::ostream& out, const Animal& animal);
ostream & operator<<(ostream & out, const Animal& animal)
{
out << animal.age << "," << animal.size << endl;
}
This is in the .h of my Abonne class. I have a inherited class of this Abonne class named Etudiant. I wish to override the << operator in the Etudiant class again, but I want it to call the operator<< of the base class Abonne in the definition of the Etudiant class, plus add more. I tried this:
friend ostream& operator<<(ostream& out, const Dog& dog);
ostream& operator<<(ostream& out, const Dog& dog)
{
return out << dog << endl;
}
It's not working, recalling the << of itself and recursiving till it crashes.
How should I proceed?
Thank you.
Easy! You need to invoke the version that takes an Abonne. So simply do that:
return out << static_cast<const Abonne&>(etudiant) << " ... and more" << endl;
// ^^^^^^^^^^^^^^^^^^^^^^^^^^

Overriding of operator<< in c++

I'm working on a project for my school in C++
I have 2 class : Employe and Teacher.
Teacher derived from Employe and has overrides of his functions.
We override the operator << to print some information of the Employes or Teachers.
Each class has a const int attribute LevelAcces_.
For Employe, it's 5 and for Teacher it's 20.
when I create an Teacher in my main.cpp, I call the override of operator<< of Teacher to print his information.
So this function is called :
ostream& operator<<(ostream& os, const Teacher& pTeacher){
os << (pTeacher);
return os;
}
But, the function calls itself with the line "os << (pTeacher);" and does a loop that causes a stack overflow.
I want that the line "os << (pTeacher)" calls the operator<< of my class Employe and not of my class Teacher.
Override of operator<< in Employe :
ostream& operator<<(ostream& os, const Employe& pEmploye){
os << "Name: " << pEmploye.name_ << endl;
os << "Class: " << pEmploye.getClass() << endl;
os << "LevelAcces: " << pEmploye.getLevelAccess() << endl;
return os;
}
I tried to cast my Teacher into Employe but when it prints the message, LevelAcces is 5 (and I want 20, because my Employe is a Teacher).
I also tried to use Employe::operator<< but operator<< is not a member of Employe so it doesn't work...
So, here is my question :
How can I do to use my operator<< of Employe in my operator<< of Teacher and print the right information (LevelAccess = 20 and not 5) ?
I was also thinking of "virtual" but our professor tells us that there is not need to use this word.
Thanks in advance :)
Here is a more complete code :
main.cpp:
Teacher Garry("Garry");
cout << Garry << endl;
Employe.cpp :
#include "Employe.h"
using namespace std;
Employe::Employe(){
name_ = "";
}
Employe::Employe(string pName){
name_ = pName;
}
string Employe::getName() const{
return name_;
}
unsigned int Employe::getLevelAccess() const{
return levelAccess_;
}
string Employe::getClass() const{
return typeid(*this).name();
}
ostream& operator<<(ostream& os, const Employe& pEmploye){
os << "Name: " << pEmploye.name_ << endl;
os << "Class: " << pEmploye.getClass() << endl;
os << "LevelAcces: " << pEmploye.getLevelAccess() << endl;
return os;
}
With this in Employe.h :
private:
static const unsigned int LevelAccess_ = 5;
Teacher.cpp :
#include "teacher.h"
using namespace std;
Teacher::Teacher(string pName){
nom_ = pName;
}
unsigned int Teacher::getLevelAccess() const{
return(Employe::getLevelAccess() + accessTeacher_);
}
string Teacher::getClass() const{
return typeid(*this).name();
}
ostream& operator<<(ostream& os, const Teacher& pTeacher){
os << (pTeacher);
return os;
}
With this is Teacher.h :
static const unsigned int accesTeacher_ = 15;
What I'd do is the following: define only one
ostream& operator<<(ostream& os, const Employe& pEmploye)
{
return pEmploye.display(os);
}
for the base of the hierarchy,
in which you call a protected member function virtual display() that is overridden by each derived class and to which the display is being delegated. This is sometime call the NVI (non-virtual interface) idiom. It works like this:
class Employee
{
// ...
friend ostream& operator<<(ostream& os, const Employee& pEmployee)
{
return pEmployee.display(os);
}
protected:
virtual ostream& display(ostream& os) const
{
// implement it here
return os;
}
};
class Teacher: public Employee
{
// ....
protected:
ostream& display(ostream& os) const override
{
// implement it here
return os;
}
};
You can use a cast:
os << static_cast<const Employe &>(pTeacher);
The & is important.
To make the call to the member function call Teacher::getLevelAccess() from an Employe reference, you have to make that function virtual. (Do this in teacher.h). getClass() should be virtual also.
NB. You keep saying things like "Override of operator<< in Employe :" , however you do not have overloaded operator<< in Employe . You have a free function which takes Employe as argument.

Use print function for output of overloaded << operator?

I have successfully overloaded the '<<' operator which I believe is referred to as the insertion operator. I have a print function which prints the information of an instance of a card object, how can I call this print function when the operator is used
example:
Card aCard("Spades",8); //generates an 8 of spades card object
aCard.Print(); // prints the suit and value of card
cout << aCard << endl; // will print something successfully but how can I get the same results as if I were to call the print function?
In my implementation file card.cpp I have overloaded the << for use with my card class.
Card.cpp
void Card::Print()
{
std::cout << "Suit: "<< Suit << std::endl;
std::cout << "Value:" << Value << std::endl;
}
std::ostream& operator<<(std::ostream &out, const Card &aCard)
{
Print();//this causes an error in the program
}
Card.h
class Card
{
public:
std::string Suit;
int Value;
Card(){};
Card(std::string S, int V){Suit=S; Value=V};
void Print();
friend std::ostream& operator<<(std::ostream&, const Card&)
};
You do only want one implementation. You could either make a Print function that takes an ostream and performs all of the print logic then call it from Print() and operator<<
void Card::Print()
{
Print(std::cout);
}
std::ostream& operator<<(std::ostream &out, const Card &aCard)
{
Print(out);
}
void Card::Print(std::ostream &out)
{
out << "Suit: "<< Suit << std::endl;
out << "Value:" << Value << std::endl;
return out;
}
Or you could have the operator<< contain the print logic and call operator<< from Print:
void Card::Print()
{
std::cout << *this;
}
std::ostream& operator<<(std::ostream &out, const Card &aCard)
{
out << "Suit: "<< Suit << std::endl;
out << "Value:" << Value << std::endl;
return out;
}
You need aCard.Print() in operator<< not Print()
std::ostream& operator<<(std::ostream &out, const Card &aCard)
{
aCard.Print();
}
You don't say what the error is but basically you're calling a globally defined Print() function or a function that doesn't exist with your code as it stands.

<< operator overloading as a class method in c++

I want to overload the << operator for my class Complex.
The prototype is the following:
void Complex::operator << (ostream &out)
{
out << "The number is: (" << re <<", " << im <<")."<<endl;
}
It works, but I have to call it like this: object << cout for the standart output.
What can I do to make it work backwards, like cout << object?
I know that the 'this' pointer is by default the first parameter sent to the method so that's why the binary operator can work only obj << ostream. I overloaded it as a global function and there were no problems.
Is there a way to overload the << operator as a method and to call it ostream << obj?
I would just use the usual C++ pattern of free function. You can make it friend to your Complex class if you want to make Complex class's private data members visible to it, but usually a complex number class would expose public getters for real part and imaginary coefficient.
class Complex
{
....
friend std::ostream& operator<<(std::ostream &out, const Complex& c);
private:
double re;
double im;
};
inline std::ostream& operator<<(std::ostream &out, const Complex& c)
{
out << "The number is: (" << c.re << ", " << c.im << ").\n";
return out;
}
You could write a free stand operator<< function, try:
std::ostream& operator<< (std::ostream &out, const Complex& cm)
{
out << "The number is: (" << cm.re <<", " << cm.im <<")." << std::endl;
return out;
}
You can define a global function:
void operator << (ostream& out, const Complex& complex)
{
complex.operator<<(out);
}

How to define class-specific << operator in C++

Given a class such as:
class Person
{
private:
char *name;
public:
Person()
{
name = new char[20];
}
~Person()
{
delete [] name;
}
}
I want to print to print the name from an instance of this, using a statement like the following:
cout << myPerson << endl;
What do I need to do to define the << output operator for this class?
add this in the class:
friend std::ostream& operator<< (std::ostream& out, const Person& P);
and then define the operator<< something like this:
std::ostream& operator<< (std::ostream& out, const Person& P) {
out << P.name;
return out;
}
Define a member function print() that takes an ostream as an argument. Then let the overloaded operator<< call this member function. This way you can avoid using friend. Example:
void YourClass::print(ostream& out) const
{
//implement printing ...
}
ostream& operator<<(ostream& out, const YourClass& m)
{
m.print(out);
return out;
}