Use print function for output of overloaded << operator? - c++

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.

Related

C++: multiple operator definitions in different namespaces

I'm troubled by conflict between two definitions of operator<<.
Suppose that I've been a great fan of ACE library and been using ACE_Time_Value in my code. One day I noticed ACE 6.x was out and tried to migrate my code from ACE 5.x to 6.x. Then I got a problem: ACE 6.x newly introduced operator<<(std::ostream &, const ACE_Time_Value &) in the global namespace, but my code had implemented my own version of operator<< since 5.x era, and two operator<< conflicted. Unfortunately the output from the "official" operator<< is unsatisfactory and I need to keep using my own version. How can I pretend there's no "official" operator<< in the global namespace? Luckily(?) all my code is under my own namespace.
Conceptually my problem can be summarized as:
#include <iostream>
using namespace std;
struct ACE_Time_Value { };
ostream &operator<<(ostream &os, const ACE_Time_Value &) { os << "Apple" ; }
void foo(const ACE_Time_Value &) { cout << "Cherry" << endl; }
namespace mine {
ostream &operator<<(ostream &os, const ACE_Time_Value &) { os << "Banana" ; }
void foo(const ACE_Time_Value &) { cout << "Durian" << endl; }
void bar() {
ACE_Time_Value t;
::mine::foo(t); // OK
// cout << "The current time is " <<
// t << endl; // error: ambiguous overload for 'operator<<'
}
}
int main() {
mine::bar();
}
http://ideone.com/NJXIz9
You can do something like below and make use of inheritance:
#include <iostream>
using namespace std;
struct ACE_Time_Value { };
ostream &operator<<(ostream &os, const ACE_Time_Value &) { os << "Apple" ; return os; }
void foo(const ACE_Time_Value &) { cout << "Cherry" << endl; }
namespace mine {
struct New_ACE_Time_Value: ACE_Time_Value {};
ostream &operator<<(ostream &os, const New_ACE_Time_Value &) { os << "Banana" ;
return os;
}
void foo(const ACE_Time_Value &) { cout << "Durian" << endl; }
void bar() {
New_ACE_Time_Value t;
::mine::foo(t); // OK
cout << "The current time is " <<
t << endl; // error: ambiguous overload for 'operator<<'
}
}
Probably you should also make 'NewACE_Time_Value' non copyable to shrug off object slicing issues.
This is how I would solve your conceptual example:
#include <iostream>
using namespace std;
struct ACE_Time_Value { };
namespace ACE
{
ostream &operator<<(ostream &os, const ACE_Time_Value &) { os << "Apple" ; return os; }
}
void foo(const ACE_Time_Value &) { cout << "Cherry" << endl; }
namespace mine {
ostream &operator<<(ostream &os, const ACE_Time_Value &) { os << "Banana" ; return os; }
void foo(const ACE_Time_Value &) { cout << "Durian" << endl; }
void bar() {
ACE_Time_Value t;
::mine::foo(t); // OK
cout << "The current time is " << t << endl;
}
}
int main() {
mine::bar();
}
Since ACE is open-source, it shouldn't be too hard to apply the same modifications so that their <<operator overload is wrapped inside a namespace.
First, you should add "return os;" in our operator overloading (<<).
Second, add Preprocessor directives to one of two << overloading like this:
#ifdef Oper
ostream &operator<<(ostream &os, const ACE_Time_Value &)
{
os << "Banana" ; return os;
}
#endif
I ended up in defining a wrapper object with operator<<.
namespace mine {
void foo(const ACE_Time_Value &) { cout << "Durian" << endl; }
struct AceTimePrinter {
const ACE_Time_Value &tv;
AceTimePrinter(const ACE_Time_Value &tv) : tv(tv) { }
inline friend std::ostream &operator<<(
std::ostream &os, const AceTimePrinter &o) {
const ACE_Time_Value &tv = o.tv;
return os << "Durian" ;
}
};
void bar() {
ACE_Time_Value t;
::mine::foo(t); // OK
cout << "The current time is " <<
AceTimePrinter(t) << endl;
}
}
We chose not to use inheritance because we cannot change existing method signatures in the ACE reactor framework, such as virtual int handle_timeout (const ACE_Time_Value &current_time, const void *act=0)

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.

Ostream << operator overloading and it's return type

I learnt how to do operator overloading of Stream Insertion Operator. But one doubt remains.
#include<iostream>
class INT
{
int i;
friend std::ostream& operator<<(std::ostream&,INT&);
public:
INT():i(100){}
};
std::ostream& operator<<(std::ostream& obj,INT & data)
{
obj<<data.i;
return obj;
}
int main()
{
INT obj;
std::cout<<obj;
}
What significance return obj; has?
Do that return have any use further?
Are We forced to do that return because of the syntax of the operator<< without any usefulness?
Remember how you can write code like this:
cout << "The data is: " << somedata << endl;
This is actually the same as:
((cout << "The data is: ") << somedata) << endl;
For this to work, the << operator has to return the stream.

Operator overloading << error

I get the compiler error
no match for 'operator<<' in 'std::cout << VertexPriority(2, 4u)'
In the main class referred to this operator overloading, but I can't undestand where the error is.
Here there is the operator overloading line, I implemented it inside the class definition.
std::ostream& operator<<(std::ostream& out) const { return out << "Vertex: " << this->vertex << ", Priority: " << this->priority; }
vertex and priority are integer and unsigner integer.
In the main class I'm trying to doing this:
std::cout << VertexPriority(2, 3) << std::endl;
Define it like this:
class VertexPriority {
...
friend std::ostream& operator<< (std::ostream& out, const VertexPriority& vp);
};
std::ostream& operator<< (std::ostream& out, const VertexPriority& vp) {
return out << "Vertex: " << vp.vertex << ", Priority: " << vp.priority;
}
The friend keyword is necessary if VertexPriority::vertex or VertexPriority::priority are not public.
For more help, read this tutorial: http://www.learncpp.com/cpp-tutorial/93-overloading-the-io-operators/

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