I am trying to overload the << operator in order to print objects of classes, I tried making a friend function of the operator and then declaring it in below the Queue class, I have not written anything inside the code block here is what I have, it wont compile, it will crash instantly, thanks in advance.
#include <string>
#include <vector>
#include <iostream>
using namespace std;
class Employee{
protected:
long empId;
string empName;
string email;
public:
Employee(){}
Employee(long i, string n){
empName = n,
empId =i;
email = "Unknown";
}
};
class Student{
protected:
long stId;
int year;
string email;
string schoolName;
public:
Student(){}
Student(long i, int y, string sn){
stId = i;
year =y;
email = "Unknown";
schoolName=sn;
}
};
template<class T>
class Queue{
protected:
vector<T> theQ;
public:
void Push(T item);
T pop();
void ReadAnItem();
void PrintQ();
**template<T>** edit
friend ostream& operator<< (ostream& is, const Queue<T>& theQ);
};
template<class T>
ostream& operator<< (ostream& os, const Queue<T>& theQ){
**os << theQ.Print();** Edit
return os;
}
template<class T>
void Queue<T>::ReadAnItem(){
T item;
cout << "Enter the data please: " << endl;
cin >> item;
Push(item);
}
template<class T>
void Queue<T>::Push(T item){
theQ.front() = item;
}
template<class T>
void Queue<T>::PrintQ(){
cout << "The content of the array is as follows: " << endl;
for (int i=0; i< theQ.size(); i++){
cout << theQ[i] << **endl;** I get an "invalid overload of endl"
}
}
You should declare that friend function as a template:
template <class U>
friend ostream& operator<< (ostream& is, const Queue<U>& theQ);
Your operator<<
function is a template function, so note that inside friend
declaration:
friend ostream& operator<< <T>(ostream& is, const Queue<T>& theQ);
This is not the as Andy's variant, as Andy's variant allows this:
#include <iostream>
template <class T>
class A
{
public:
A(T d): data(d){}
private:
// friend is any template instance of function foo, and not just foo<T>!
template <class U>
friend void foo(A<U>& t);
T data;
};
A<int> ai(1);
template <class T>
void foo(A<T>& t)
{
// A<int> will accept foo<double> as friend
std::cout << ai.data << std::endl;
std::cout << t.data << std::endl;
}
int main()
{
A<double> ad(2);
foo(ad);
return 0;
}
However, in my case, you need to add few forward declarations, in order to make this right:
#include <iostream>
// 2. But before that you need to forward-declare your class, so the function
// can know about the class.
template <class T>
class A;
// 1. You need to forward-declare your foo function...
template <class T>
void foo(A<T>& t);
template <class T>
class A
{
public:
A(T d): data(d){}
private:
friend void foo<T>(A<T>& t);
T data;
};
A<int> ai(1);
template <class T>
void foo(A<T>& t)
{
// error: ‘int A<int>::data’ is private within this context
//std::cout << ai.data << std::endl;
std::cout << t.data << std::endl;
}
int main()
{
A<double> ad(2);
foo(ad);
}
Here's your code, but you need more work to do:
#include <string>
#include <vector>
#include <iostream>
using namespace std;
class Employee{
protected:
long empId;
string empName;
string email;
public:
Employee(){}
Employee(long i, string n){
empName = n,
empId =i;
email = "Unknown";
}
};
class Student{
protected:
long stId;
int year;
string email;
string schoolName;
public:
Student(){}
Student(long i, int y, string sn){
stId = i;
year =y;
email = "Unknown";
schoolName=sn;
}
};
template<class T>
class Queue;
template<class T>
ostream& operator<< (ostream& os, const Queue<T>& theQ);
template<class T>
class Queue{
protected:
vector<T> theQ;
public:
void Push(T item);
T pop();
void ReadAnItem();
void PrintQ() const;
friend ostream& operator<< <T> (ostream& is, const Queue<T>& theQ);
};
template<class T>
ostream& operator<< (ostream& os, const Queue<T>& theQ){
// I will just use this, but it should receive ostream
theQ.PrintQ();
return os;
}
template<class T>
void Queue<T>::ReadAnItem(){
T item;
cout << "Enter the data please: " << endl;
cin >> item;
Push(item);
}
template<class T>
void Queue<T>::Push(T item){
// this aint gonna work! Use std::deque and push_front! theQ.front() = item;
}
template<class T>
void Queue<T>::PrintQ() const{
cout << "The content of the array is as follows: " << endl;
for (int i=0; i< theQ.size(); i++){
// You need to overlload operator<< for student to make this work! cout << theQ[i] << endl;
}
}
int main()
{
Queue<Student> s;
s.Push(Student());
std::cout << s;
return 0;
}
Note - this code is not perfect (nor good), it just shows you how to solve this particular problem. You need to move body of PrintQ()
method to operator<<
or to make your PrintQ
to accept and return ostream&
. Also, I've already marked it as a const
, as it doesn't change state of the class. Also, you don't have operator<<
for student, so you are not able to output it into the ostream&
. Also, vector.first() = s
will always wipe your first element (it will copy s
into the first element of the vector using operator=
), or it will fail, if there's no first element. I'm sure there's other bugs, but these are only that I saw while trying your program.
Edit
For each different class, you need to have different operator<<
. So, change the Student
to:
class Student{
protected:
long stId;
int year;
string email;
string schoolName;
friend ostream& operator<<(ostream& os, const Student& s);
public:
Student(){}
Student(long i, int y, string sn){
stId = i;
year =y;
email = "Unknown";
schoolName=sn;
}
};
and add another operator<<
body:
ostream& operator<<(ostream& os, const Student& s)
{
os << s.stId << s.year << s.email << std::endl;
return os;
}
Also, do this for Employee
. And you should consider moving common fields from Student
and Employee
to base class Person
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.