1

我已经在链接类实现中重载了'< <'运算符,并且我在主函数中声明了.cpp文件,但它不起作用,并且此错误发生: 未定义参考操作< &列表)我已经完成<<运算符超载但它不工作

这是ostream的功能的linkedlist.h文件中声明:

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

,这是ostre实施AM功能:

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 

我希望你们能帮助我,在你的帮助是非常赞赏

+1

你是否在头文件中实现了它? – juanchopanza

+1

比较你的声明和你的定义(第二个参数)。 – lapk

+0

为什么要将'current'节点放在实际的列表类中? –

回答

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)。然后你在课堂外定义它。

如果您想指定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.P.S。由于您在operator <<的中使用operator <<SavingAccount类型,因此您还需要为SavingAccount定义operator <<

自我注意:不要回答问题的评论'节到另一个答案;)。

+0

我已经把内容拉到我的标题文件和更新所有内容,我已经取消了const,现在我正面临一个错误: 'std :: ostream&LinkedListstd :: operator <<(std :: ostream&os,LinkedList &list)必须只有一个参数“ – Alladin

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语法,并且具有一些优点(如果需要,请阅读它)。

希望这会有所帮助!

+0

thx男人,我改正了它,但仍然不工作:( – Alladin

+0

@Alladinsaoudi你可以发布你的LinkedList类的代码吗? – Oleksiy

+0

我已经编辑了这个问题,你可以在那里看到代码。谢谢^^ – Alladin

0

除了非常病态的情况下,“ouptut”操作不应该改变待输出值,所以正确的函数原型应和

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

,你不应该分配新值list成员(如在list.current = list.start)。 你最好重新思考逻辑,以及...

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