Я сделал перегрузку оператора & lt; & lt; но это не работает

я перегружен<<‘оператор в реализации связанного класса, и я объявил .cpp файл в моей основной функции, но он не работает, и возникает эта ошибка:
неопределенная ссылка на оператора<& список)

это объявление функции ostream в файле connectedlist.h:

  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

Я надеюсь, что вы, ребята, можете помочь мне с этим, ваша помощь очень ценится

1

Решение

Хорошо, после того, как вы опубликовали свой код, кажется, что ваша проблема в том, что вы разбили LinkedList Объявление шаблона и реализация между заголовком и исходным файлом. Если вы не выполняете явную реализацию в исходном файле, вы не можете сделать это: вы не можете разделить объявление шаблона и реализацию, они должны быть в одном заголовке.

Вы должны поместить содержание вашего LinkedList.cpp в LinkedList.h, полностью избавьтесь от исходного файла и просто включите обновленный заголовок там, где он вам нужен.

Постскриптум Кроме того, изменение объекта через 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 не использовался в параметрах шаблона в bar объявление класса). И тогда вы определяете это вне класса.

Если вы хотите указать аргументы шаблона по умолчанию для 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 > & )
{
...
}

И еще один последний П.П.П.П. (надеюсь!). Так как вы используете operator << для типа SavingAccount в вашем operator << за LinkedListнужно определить operator << за SavingAccount тоже.

ПРИМЕЧАНИЕ ДЛЯ СЕБЯ: Не отвечайте на вопросы в разделе комментариев на другой ответ;).

1

Другие решения

Я не уверен, является ли это причиной ошибки, но определение вашей функции отличается от объявления вашей функции:

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

Петр Будник верно, вам нужно сохранить реализацию шаблона в том же файле, что и ваше определение.

Есть одна вещь, которую он не упомянул (и это, вероятно, вызывает у вас проблемы): вам нужно четко указать, что вы используете 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;
}

Постскриптум

Могу ли я предложить вам использовать nullptr вместо 0 или же NULL? Это новый синтаксис C ++ 11 и имеет несколько преимуществ (читайте об этом, если хотите).

Надеюсь это поможет!

1

Помимо очень патологических случаев, операция «выход» не должна изменять значение, которое будет выводиться, поэтому надлежащий прототип функции должен быть

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

и вы не должны назначать новые значения list члены (как в list.current = list.start).
Тебе лучше переосмыслить логику …

Кроме того, функция шаблона должна быть реализована в заголовках, а не в файлах cpp.

0