如何将用户定义的类用作模板类的类型并正确地重载<<这两个班?

时间:2013-11-14 01:41:41

标签: c++ class templates stl overloading

首先,我希望我能够解释得这么好。我想要完成的是创建一个学生和获胜者的Trio(模板类)(来自他们的课程)。另外,我试图重载<< Student和Winner类中的运算符,以便可以使用cout输出它们。目前,我遇到的问题是编译器给了我一个链接错误,学生和Winner重载<<运营商。任何帮助表示赞赏。

感谢高级。

这是我到目前为止的代码:

#include <algorithm>;
#include <cstdlib>;
#include <ctime>;
#include <deque>;
#include <iostream>;
#include <list>;
#include <stack>;
#include <string>;
#include <set>;


using namespace std;

template <class T>
class Trio
{ 
public:     
    Trio();    
    Trio(T first_value, T second_value, T third_value);    
    void set_element(int position, T value);
    T get_element(int position) const;
    void set_all (T first_value, T second_value, T third_value);
private:
    T first; 
    T second;
    T third;

    friend ostream& operator << (ostream& os, const Trio<T>& x)
    {
        os << "Trio Values: " << x.first << ", " << x.second << ", " << x.third;
        return os;
    }
};

class Student 
{
    public:
        Student();
        Student(string name_value, double gpa_value);
    private:
        double gpa;
        string name;
        friend ostream& operator << (ostream& os, const Student<T>& a)
        {
            os << "Name: " << a.name << endl;
            os << "GPA: " << a.gpa << endl;
            return os;
        }
};

class Winner 
{
    public:
        Winner();
        Winner(string competition_value, string name_value);
    private:
        string competition;
        string name;
        friend ostream& operator << (ostream& os, const Winner& a)
        {
            os << "Competition: " << a.competition << endl;
            os << "Name: " << a.name << endl;
            return os;
        }
};

int main()
{
    Trio <int> xyz_coordinates(1,2,3);
    Trio <char> name_initials('D','J','C');
    Trio <string> full_name("Bill", "Tom", "Smith");
    Trio <string> car("GMC", "Sierra 1500", "5058dc");
    Student s1("Bill", 4.0), s2("Mary", 3.98), s3("Joe", 3.95);
    Winner w1("NBA Champions", "Celtics"), w2("Superbowl Winners", "Patriots"), w3("World Series", "Red Sox");
    Trio <Student> top_students(s1,s2,s3);
    Trio <Winner> winners(w1,w2,w3);

    xyz_coordinates.set_element(1, 0);
    cout << xyz_coordinates << endl;
    cout << "Value: " << xyz_coordinates.get_element(1) << endl;
    xyz_coordinates.set_all(1,2,3);
    cout << xyz_coordinates << endl;
    cout << endl;

    name_initials.set_element(1, 'A');
    cout << name_initials << endl;
    cout << "Value: " << name_initials.get_element(1) << endl;
    name_initials.set_all('D','J','C');
    cout << name_initials << endl;
    cout << endl;

    full_name.set_element(1, "Dere");
    cout << full_name << endl;
    cout << "Value: " << full_name.get_element(1) << endl;
    full_name.set_all("Derek","John","Campaniello");
    cout << full_name << endl;
    cout << endl;

    car.set_element(3, "5897av");
    cout << car << endl;
    cout << "Value: " << car.get_element(2) << endl;
    car.set_all("Ford","F150","3465d");
    cout << car << endl;

    cout << top_students << endl;
    cout << winners << endl;

    /*************************************/
    /*          List of Ints             */
    /*************************************/
    cout << endl;
    list <int> alist;
    list<int>::const_iterator listiter1;

    alist.push_back(17);
    alist.push_back(87);
    alist.push_back(22);
    alist.push_back(26);
    alist.push_back(24);

    cout << "List A: \n";
    for (listiter1 = alist.begin(); listiter1 != alist.end(); listiter1++)
    {
        cout << *listiter1 << " ";
    }
    cout << endl;

    alist.pop_back();

    cout << "List A after popping back: \n";
    for (listiter1 = alist.begin(); listiter1 != alist.end(); listiter1++)
    {
        cout << *listiter1 << " ";
    }
    cout << endl;

    alist.sort();
    cout << "List A after being sorted: \n";
    for (listiter1 = alist.begin(); listiter1 != alist.end(); listiter1++)
    {
        cout << *listiter1 << " ";
    }
    cout << endl;

    cout << endl;

    /*************************************/
    /*          Deque of Chars           */
    /*************************************/
    deque <char> adeque;
    deque<char>::const_iterator dequeiter1;

    adeque.push_back('A');
    adeque.push_back('B');
    adeque.push_back('C');
    adeque.push_back('D');

    cout << "Deque A: \n";
    for (dequeiter1 = adeque.begin(); dequeiter1 != adeque.end(); dequeiter1++)
    {
        cout << *dequeiter1 << " ";
    }
    cout << endl;

    adeque.pop_front();
    cout << "Deque A after being popped in the front: \n";
    for (dequeiter1 = adeque.begin(); dequeiter1 != adeque.end(); dequeiter1++)
    {
        cout << *dequeiter1 << " ";
    }
    cout << endl;

    cout << "Deque A after being randomized: \n";
    srand(time(0));
    random_shuffle(adeque.begin(), adeque.end());
    for (dequeiter1 = adeque.begin(); dequeiter1 != adeque.end(); dequeiter1++)
    {
        cout << *dequeiter1 << " ";
    }
    cout << endl;


    /*************************************/
    /*          Set of Strings           */
    /*************************************/

    cout << endl;
    set <string> aset;
    set <string> bset;
    set<string>::const_iterator iter1;

    aset.insert("ABC");
    aset.insert("DEF");
    aset.insert("GHI");

    bset.insert("RST");
    bset.insert("UVW");
    bset.insert("XYZ");

    cout << "Set A contains: \n";

    for (iter1 = aset.begin(); iter1 != aset.end(); iter1++)
    {
        cout << *iter1 << " ";
    }
    cout << endl;

    cout << "Set A with DEF Erased: \n";
    aset.erase("DEF");
    for (iter1 = aset.begin(); iter1 != aset.end(); iter1++)
    {
        cout << *iter1 << " ";
    }
    cout << endl;

    aset.swap(bset);

    cout << "Swapped Sets: \n";

    cout << "Set A: \n";
    for (iter1 = aset.begin(); iter1 != aset.end(); iter1++)
    {
        cout << *iter1 << " ";
    }
    cout << endl;

    cout << "Set B: \n";
    for (iter1 = bset.begin(); iter1 != bset.end(); iter1++)
    {
        cout << *iter1 << " ";
    }
    cout << endl;

    /*****************************/
    /*     Stack of Student      */
    /*****************************/
    stack <Student> astack;

    astack.push("Student 1");


    /*****************************/
    /*    Queue of Winners       */
    /*****************************/
    cout << endl;
    system("pause");
}

template <class T>
Trio<T>::Trio(T first_value, T second_value, T third_value)
{
    first = first_value;
    second = second_value;
    third = third_value;
}

template <class T>
void Trio<T>::set_element(int position, T value)
{
      if (position == 1)
      {
          first = value;
          cout << "First value set to: " << value << endl;
      }     
      else if (position == 2)
      {        
          second = value;
          cout << "Second value set to: " << value << endl;    
      }
      else if (position == 3)
      {
          third = value;
          cout << "Third value set to: " << value << endl;
      }
      else
      {
          cout << "Element not set." << endl;
      }

}

template <class T>
T Trio<T>::get_element(int position) const
{
    if (position == 1)
      {
        return first;
      }   
    else if (position == 2)
      {        
          return second;     
      }
    else if (position == 3)
      {
         return third;
      }
    else
    {
        T null;
        return null;
    }
}

template <class T>
void Trio<T>::set_all (T first_value, T second_value, T third_value)
{
    first = first_value;
    second = second_value;
    third = third_value;
    cout << "Values set as follows: " << first << ", " << second << ", " << third << endl;
}

Student::Student(string name_value, double gpa_value)
{
    name = name_value;
    gpa = gpa_value;
}

Winner::Winner(string competition_value, string name_value)
{
    competition = competition_value;
    name = name_value;
}

1 个答案:

答案 0 :(得分:2)

以下是明显的错误:

  1. #include指令接受终止分号,尽管编译器可能只会对此问题发出警告。
  2. Student不是模板,即<T>输出运算符的声明中存在多余的Student
  3. 语句astack.push("Student 1");将无法编译,因为Student实际上需要两个构造函数参数而不是一个。您需要显式构造Student对象。
  4. StudentWinner声明但未定义的默认构造函数。
  5. 解决问题之后,代码应该编译并链接。