输出运算符重载队列类C ++

时间:2013-11-25 17:33:53

标签: c++ templates queue overloading

我正在尝试重载<<运算符为了打印类的对象,我尝试制作运算符的朋友函数,然后在Queue类下面声明它,我没有在代码块里面写任何东西,这里是我的,它不会编译,它会崩溃立刻,谢谢你。

#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"
    }
}

2 个答案:

答案 0 :(得分:2)

您应该将该朋友的功能声明为模板:

template <class U>
friend ostream& operator<< (ostream& is, const Queue<U>& theQ);

答案 1 :(得分:0)

您的operator<<函数是一个模板函数,请注意friend声明内部:

friend ostream& operator<< <T>(ostream& is, const Queue<T>& theQ);

这不是Andy的变体,因为Andy的变体允许这样:

#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;

}

但是,在我的情况下,你需要添加一些前向声明,以便做到这一点:

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

}

这是您的代码,但您需要做更多工作:

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

注意 - 这段代码并不完美(也不好),它只是告诉你如何解决这个特殊问题。您需要将PrintQ()方法的正文移至operator<<或让PrintQ接受并返回ostream&。此外,我已将其标记为const,因为它不会更改类的状态。此外,您没有学生operator<<,因此您无法将其输出到ostream&。此外,vector.first() = s将始终擦除您的第一个元素(它会使用soperator=复制到向量的第一个元素中,否则如果没有第一个元素,它将失败。我确定还有其他错误,但这些只是我在尝试你的程序时看到的。

修改

对于每个不同的班级,您需要有不同的operator<<。因此,请将Student更改为:

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

并添加另一个operator<<正文:

ostream& operator<<(ostream& os, const Student& s)
{
   os << s.stId << s.year << s.email << std::endl;
   return os;
}

另外,为Employee执行此操作。您应该考虑将常用字段从StudentEmployee移至基类Person