我已经完成了<<运算符重载,但它'It’不起作用

i have done the <<operator overloading but it's not working

本文关键字:lt 但它 It 不起作用 重载 运算符      更新时间:2023-10-16

我已经重载了'<lt;'运算符,并且我在主函数中声明了.cpp文件,但它不起作用,出现了以下错误:对运算符的未定义引用<amp;列表)

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

在主函数中,我创建了一个列表,其中包含SavingAccount类中的对象

LinkedList <SavingAccount> list;

并且错误发生在这一行的主要功能中:

 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

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

好吧,发布代码后,问题似乎是在头文件和源文件之间拆分LinkedList模板声明和实现。除非你在源文件中进行显式实例化,否则你不能这样做:你不能将模板声明和实现分开,它们必须在一个头中。

您需要将LinkedList.cpp的内容放在LinkedList.h中,完全去掉源文件,只需在需要的地方包含更新的标头。

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

p.p.S.如果您确实希望并打算修改通过const引用访问的类的对象中的一些数据成员,则需要将这些数据成员声明为mutable

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

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

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

如果您想为foo指定默认的模板参数,那就更麻烦了。不能在friend声明中使用默认模板参数,因此必须转发声明所有内容:

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 > & )
{
 ...
}

还有最后一次p.p.p.S(我希望!)。由于您在operator <<中使用operator <<作为类型SavingAccount作为LinkedList,因此还需要为SavingAccount定义operator <<

自我注意:不要用另一个答案回答评论部分的问题;)。

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

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

此外,如果您计划修改传入的LinkedList,请删除const

以下是(大致)您的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语法,有一些好处(如果你愿意,请阅读)。

希望这能有所帮助!

除了非常病理的情况外,"ouptut"操作不应该改变要输出的值,因此正确的功能原型应该是

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

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

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

相关文章: