Pergunta

I am working on a project for class that is a sort of payroll. Part of the prompt says

"You may define a friend function that overloads << for displaying the Employee object information(i.e. the overloading << function will call the virtual print function.)"

I know what a friend function is, but I don't recall learning about the overloading << part. I tried searching for some easy copy paste implementation... but my compiler flares up no matter what I try.

How do I go about actually implementing this? Here's the code I have so far:

#include <iostream>
#include <string>

using namespace std;

//Base class
class Employee
{
public:
    Employee(string a, string b, string c, string d);
    ~Employee();
    int virtual earnings();
    void virtual print();
protected:
    string first, last, brithday, department;
};

Employee::Employee(string f, string l, string b, string d)
{
    first = f;
    last = l;
    brithday = b;
    department = d; //department code
    cout << "Employee created." << endl;
}

Employee::~Employee(void)
{
    cout << "Employee deleted." << endl;
}

int Employee::earnings()
{
    int earnings = 100; //To be added
    return earnings;
}

void Employee::print()
{
    //IDK 
}
Foi útil?

Solução

Don't let the << operator confuse you. Overloaded operators are, at the end of the day, just another way to name functions.

If you have this piece of code:

int i = 1;
std::string s = "x";
double d = 0.5;
std::cout << s << i << d;

Then this is just another way of saying:

int i = 1;
std::string s = "x";
double d = 0.5;
std::operator<<(std::cout, s).operator<<(i).operator<<(d);

Which, by the way, makes it more obvious that the chaining calls work because operator<< returns a reference to the stream itself. Note that there are two different kinds of operator<< involved here: the one for std::string is a free-standing function taking a std::ostream reference argument, the ones for int and double are std::ostream member functions.

Equipped with this knowledge, it's easy to imagine, for a moment, that we would just be dealing with normally named functions, e.g. "print":

int i = 1;
std::string s = "x";
double d = 0.5;
print(std::cout, s).print(i).print(d);

In fact, you can imagine that there is no overloading but all of them have different names. This makes the whole thing even easier to understand:

int i = 1;
std::string s = "x";
double d = 0.5;
printStringOnStream(std::cout, s).printInt(i).printDouble(d);

If you want to provide std::ostream printing for your own class, all you have to do is do it like std::string: provide a free-standing operator<< which takes a std::ostream reference and a (const) reference to your object, and which returns a reference to the stream:

std::ostream &operator<<(std::ostream &stream, Employee const &employee)
{
    // ...
    return stream;

}

Now the // ... part is where the friend thing comes into play. In order to properly print an Employee, you'll need access to all its private members. The easiest way to provide this access without exposing it to the whole public is to declare your operator<< a friend of Employee:

class Employee
{
    // ...
    friend std::ostream &operator<<(std::ostream &stream, Employee const &employee);
}; 

std::ostream &operator<<(std::ostream &stream, Employee const &employee)
{
    stream << employee.earnings; // and so on
    return stream;
}

There you go, perfect printing for your Employee:

std::cout << "xyz" << my_employee << "abc" << 0.5 << 1;
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top