我做了<

时间:2013-08-16 12:36:40

标签: c++ data-structures linked-list operator-overloading code-separation

我重载了'<<<链接类实现中的运算符,我在我的main函数中声明了.cpp文件,但是它不起作用,并且发生以下错误: 运算符的未定义引用<&列表)

这是linkedlist.h文件中ostream函数的声明:

  friend std::ostream& operator<< (std::ostream& os, LinkedList<T>& list);

这是ostream函数的实现:

 template <typename T>
   std::ostream& operator<< (std::ostream& os, LinkedList<T> list) 
 {
  list.current = list.start;
  while(list.current != NULL)
    {
        os<< list.current->info<<" -> ";
        list.current = list.current->next;
    }
    os<<"NULL"<<endl;
    return os;
 }

在main函数中,我创建了一个包含SavingAccount类

对象的列表
LinkedList <SavingAccount> list;

并且错误发生在此行的main函数中:

 cout << list <<endl;

嗯..这是LinkedList类的实现:

#include "LinkedList.h"
#include "SavingAccount.h"
#include <cstddef>
using namespace std;

template <typename T>
LinkedList<T>::LinkedList()
{
   start = NULL;
   current = NULL;
}
template <typename T>
LinkedList<T>::~LinkedList()
  {
    // Add code.
  }

  template <typename T>
   std::ostream& operator<< (std::ostream& os,const LinkedList<T>& list) {
    list.current = list.start;
    while(list.current != NULL)
    {
        os<< list.current->info<<" -> ";
        list.current = list.current->next;
    }
    os<<"NULL"<<endl;
    return os;
  }

这是LinkedLins类的头文件:

#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#include<iostream>

using namespace std;


template <typename T>
struct Node{
    T info;
    Node<T> *next;
};

template <typename T>

class LinkedList
{
    Node<T> *start;
    Node<T> *current;
public:
    LinkedList();
    ~LinkedList();
    friend std::ostream& operator<< (std::ostream& os, const LinkedList<T>& list);

  };

#endif // LINKEDLIST_H

我希望你们可以帮助我,非常感谢你的帮助

3 个答案:

答案 0 :(得分:1)

我不确定这是否是导致错误的原因,但您的函数定义与函数声明不同:

// you left out a & (reference sign) - LinkedList<T>& list in declaration
std::ostream& operator<< (std::ostream& os, LinkedList<T> list) 

修改

Petr Budnik 是对的,您需要将模板实施保存在与定义相同的文件中。

有一件事他没有提到(这可能会导致你出现问题):你需要明确表示你使用template T超过<<重载:

template < typename T>
friend std::ostream& operator<< (std::ostream& os, LinkedList<T>& list);

另外,如果您打算修改传入的const,请删除LinkedList

这是(大致)你的LinkedList.h应该是什么样的:

template <typename T>
struct Node{
    T info;
    Node<T> *next;
};

template <typename T>
class LinkedList
{
    Node<T> *start;
    Node<T> *current;
public:
    LinkedList();
    ~LinkedList();

    template < typename T>
    friend std::ostream& operator<< (std::ostream& os, LinkedList<T>& list);


};

template <typename T>
LinkedList<T>::LinkedList()
{
    start = NULL;
    current = NULL;
}

template <typename T>
LinkedList<T>::~LinkedList()
{
    // Add code.
}

template <typename T>
std::ostream& operator<<(std::ostream& os, LinkedList<T>& list) {
    list.current = list.start;
    while (list.current != NULL)
    {
        os << list.current->info << " -> ";
        list.current = list.current->next;
    }
    os << "NULL" << endl;
    return os;
}    

P.S。

我建议您使用nullptr代替0NULL吗?它是一种新的C ++ 11语法,并且有一些好处(如果需要,请阅读它)。

希望这有帮助!

答案 1 :(得分:1)

好的,在您发布代码后,您的问题似乎是您在标头和源文件之间拆分LinkedList模板声明和实现。除非您在源文件中进行显式实例化,否则您无法执行此操作:您无法将模板声明和实现分开,它们必须位于一个标头中。

您需要将 LinkedList.cpp 的内容放在 LinkedList.h 中,完全删除源文件,并在需要的地方添加更新的标题它

P.S。另外,一般来说,通过const引用修改对象并不是一个好主意。编译器不会喜欢它。您可能想重新考虑您的设计。

P.P.S。如果您真的想要并且意味着修改您通过const引用访问的类的对象中的某些数据成员,则需要将这些数据成员声明为mutable

P.P.P.S。详细说明模板foo类的模板函数bar朋友声明,避免在评论中进行冗长的讨论。

如果你在类中定义了这样的函数及其声明,那么这是一个简单的事情 - 只需使用friend关键字。例如,friend void foo( bar< T > & ) { ... }

如果在类之外单独定义它,则需要在声明中使用略有不同的语法,并避免模板参数的隐藏:template< typename U > friend void foo( bar< U > & ) { ... }(假设U未在{{{}中的模板参数中使用1}}类声明)。然后你在课外定义它。

如果要为bar指定默认模板参数,则会变得更加棘手。您不能在foo声明中使用默认模板参数,因此您必须转发声明所有内容:

friend

最后一个P.P.P.P.S(我希望!)。由于您在template< typename T > class bar; template< typename T = int > void foo( bar< T > & ); template< typename T > class bar { template< typename U > friend void foo( bar< U > & ); }; template< typename T > void foo( bar< T > & ) { ... } operator <<中使用SavingAccount类型operator <<,因此您还需要为LinkedList定义operator <<

请自行注意:请勿在评论部分回答其他答案中的问题;)。

答案 2 :(得分:0)

除了非常病态的情况,“ouptut”操作不应该改变要输出的值,所以适当的函数原型应该

template<class T>
std::ostream& operator<<(std::ostream& s, const LinkedList<T>& list)
{
...
}

并且您不应将新值分配给list成员(例如list.current = list.start)。 你最好重新考虑逻辑......

此外,模板功能必须在头文件中实现,而不是cpp文件