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.
Related
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;
// ^^^^^^^^^^^^^^^^^^^^^^^^^^
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?
I'm a student learning c++. today, I was making a operator overload function to use it in 'cout'. following is a class that contains name, coordinates, etc.
class Custom {
public:
string name;
int x;
int y;
Custom(string _name, int x, int y):name(_name){
this->x = x;
this->y = y;
}
int getDis() const {
return static_cast<int>(sqrt(x*x+y*y));
}
friend ostream& operator << (ostream& os, const Custom& other);
};
ostream& operator << (ostream& os, const Custom& other){
cout << this->name << " : " << getDis() << endl;; // error
return os;
}
However, this code isn't working because of 'THIS' keyword that I was expecting it points to the object. I want to show the object's name and distance value. How can I solve it? I think it is similar with Java's toString method so that it will be able to get THIS.
Thanks in advance for your answer and sorry for poor english. If you don't understand my question don't hesitate to make a comment.
this is available only in member functions, but your operator<< is not a class member (declaring it as friend does not make it a member). It is a global function, as it should be. In a global function, just use the arguments you are passing in:
ostream& operator << (ostream& os, const Custom& other)
{
os << other.name << " : " << other.getDis() << endl;
return os;
}
Also note os replaced cout in the code above. Using cout was an error - the output operator should output to the provided stream, not to cout always.
I am trying to use boost::lexical_cast to convert my user defined type into an integer.
However, I get an exception. What am I missing??
class Employee {
private:
string name;
int empID;
public:
Employee() : name(""), empID(-1)
{ }
friend ostream& operator << (ostream& os, const Employee& e) {
os << e.empID << endl;
return os;
}
/*
operator int() {
return empID;
}*/
};
int main() {
Employee e1("Rajat", 148);
int eIDInteger = boost::lexical_cast<int>(e1); // I am expecting 148 here.
return 0;
}
I know I can always use the conversion operator, but just wondering why lexical cast doesn't work here.
The problem is that what you insert into the output stream is not the representation of an integer (because of the trailing << std::endl). The following fails in a similar way:
boost::lexical_cast<int>("148\n")
Removing the << std::endl makes it work:
friend std::ostream& operator << (std::ostream& os, const Employee& e) {
os << e.empID;
// ^^^^^^^^^^^^^^
// Without << std::endl;
return os;
}
I'd like to control what is written to a stream, i.e. cout, for an object of a custom class. Is that possible in C++? In Java you could override the toString() method for similar purpose.
In C++ you can overload operator<< for ostream and your custom class:
class A {
public:
int i;
};
std::ostream& operator<<(std::ostream &strm, const A &a) {
return strm << "A(" << a.i << ")";
}
This way you can output instances of your class on streams:
A x = ...;
std::cout << x << std::endl;
In case your operator<< wants to print out internals of class A and really needs access to its private and protected members you could also declare it as a friend function:
class A {
private:
friend std::ostream& operator<<(std::ostream&, const A&);
int j;
};
std::ostream& operator<<(std::ostream &strm, const A &a) {
return strm << "A(" << a.j << ")";
}
You can also do it this way, allowing polymorphism:
class Base {
public:
virtual std::ostream& dump(std::ostream& o) const {
return o << "Base: " << b << "; ";
}
private:
int b;
};
class Derived : public Base {
public:
virtual std::ostream& dump(std::ostream& o) const {
return o << "Derived: " << d << "; ";
}
private:
int d;
}
std::ostream& operator<<(std::ostream& o, const Base& b) { return b.dump(o); }
In C++11, to_string is finally added to the standard.
http://en.cppreference.com/w/cpp/string/basic_string/to_string
As an extension to what John said, if you want to extract the string representation and store it in a std::string do this:
#include <sstream>
// ...
// Suppose a class A
A a;
std::stringstream sstream;
sstream << a;
std::string s = sstream.str(); // or you could use sstream >> s but that would skip out whitespace
std::stringstream is located in the <sstream> header.
The question has been answered. But I wanted to add a concrete example.
class Point{
public:
Point(int theX, int theY) :x(theX), y(theY)
{}
// Print the object
friend ostream& operator <<(ostream& outputStream, const Point& p);
private:
int x;
int y;
};
ostream& operator <<(ostream& outputStream, const Point& p){
int posX = p.x;
int posY = p.y;
outputStream << "x="<<posX<<","<<"y="<<posY;
return outputStream;
}
This example requires understanding operator overload.