Может ли кто-нибудь помочь мне с этим вопросом, пожалуйста? Для справочной информации у меня есть три класса: Account.h
с Account.cpp
, Node.h
с Node.cpp
, LinkedList.h
с Linkedlist.cpp
и demo.cpp
, который содержит int main()
. Все текущие функции работают, за исключением распечатки связанного списка, что является основой моего вопроса.
В вопросе конкретно сказано:
Реализуйте перегруженную функцию
operator <<
, не являющуюся членом, которая используетoperator <<
изAccount
, чтобы вы могли выполнять такие операции, как:
cout << MyLinkedList << endl;
Я скопировал определенные части своего кода, связанные с этим вопросом, из LinkedList.cpp
и Account.cpp
, потому что это будет слишком долго, если я вставлю все это сюда.
Код из LinkedList.cpp
с перегруженной функцией operator <<
, «еще не работающей», показан ниже: Обратите внимание, что value_type
является typedef для Account
.
#include "LinkedList.h"
LinkedList::value_type LinkedList::getCurrent() const {
if (current != NULL) {
return current->getData();
} else {
return value_type();
}
}
ostream& operator << (ostream& out, const LinkedList& list) { // not working, compile error!
value_type current = getCurrent();
while (current != NULL) {
out << "(" << acc.getName() << "," << acc.balance() << ")" << endl;
}
return out;
}
Код от Account.cpp
показан ниже:
ostream& operator << (ostream& out, const Account& acc)
{
out << "(" << acc.getName() << "," << acc.balance() << ")" << endl;
return out;
}
Это объявления классов для моего файла node.h:
#ifndef TEKAAI_NODE
#define TEKAAI_NODE
#include "Account.h"
class Node
{
public:
// members that are externally visible
// Below are Member functions
// specifying value_type to Account using typedef
typedef Account value_type;
// Default constructor
Node();
// Parameter Constructors
Node(const value_type& initial_data, Node* initial_link);
~Node(); //destructor
void setNext(Node* n);
void setPrevious(Node* p);
Node* getNext() const;
Node* getPrevious() const;
// the data getters and setters
// Pre-condition: Current has been initialized
// Post-condition: set data
void setData(const value_type& i);
// Pre-condition: Data has been initialized
// Post-condition: returns stored data
value_type getData() const;
private:
value_type data; //the data held by the node
Node* next; //a pointer to the next node
Node* previous; //a pointer to the previous node
};
#endif
Это объявления классов в моем файле LinkedList.h:
#ifndef TEKAAI_LINKEDLIST_H
#define TEKAAI_LINKEDLIST_H
#include "Account.h"
#include "Node.h"
#include <iostream>
class LinkedList
{
public:
typedef Account value_type;
// Members that are externally visible
// These are Member functions
// Constructors
LinkedList();
// Destructor
~LinkedList();
void addToHead(const value_type& account);
void addToTail(const value_type& account);
void addCurrent(const value_type& account);
value_type removeFromHead();
value_type removeFromTail();
value_type removeFromCurrent();
// Pre-condition: LinkedList contains nodes
// Post-condition: moves current to the head
void start();
// Pre-condition: LinkedList contains nodes
// Post-condition: moves current to the tail
void end();
// Pre-condition: LinkedList contains nodes
// Post-condition: moves current one node to the right
void forward();
// Pre-condition: LinkedList contains nodes
// Post-condition: moves current one node to the left
void back();
// Pre-condition: LinkedList contains nodes
// Post-condition: returns the value of data account stored
// in current node
value_type getCurrent() const;
// Pre-condition: LinkedList is initialized, containing
// nodes
// Post-condition: returns the length of the list
int length();
private:
Node* head;
Node* tail;
Node* current;
};
ostream& operator << (ostream& out, const LinkedList& list);
#endif
Как вы можете видеть в объявлении класса LinkedList выше, мне приходится работать с ними, чтобы попытаться распечатать мой связанный список. Я хотел бы услышать ваши мысли, возможно ли распечатать мой связанный список, используя одну из вышеперечисленных функций, а также используя перегруженный оператор << из учетной записи, как указано в вопросе.
Спасибо.
ПЛЮС ПРИМЕЧАНИЕ. Просто чтобы вы знали, что я могу распечатать свой связанный список, используя функцию «Node * getHead () const;» который возвращает голову при перегрузке оператора <<, но я просто искал помощь, если можно распечатать связанный список без использования функции getHead(). Я предполагаю, что наш лектор просто баловался с нами, пытаясь заставить нас сойти с ума своей лабораторной деятельностью.
«Обратите внимание, что value_type — это typedef для учетной записи…». Было бы лучше, если бы вы просто опубликовали MRE.
Пожалуйста, покажите также полный текст вывода компилятора, в чем ошибка? Без минимального воспроизводимого примера или ошибки компилятора у нас очень мало шансов вам помочь. Наверняка LinkedList
нельзя скопировать, но вы передаете его оператору по значению, обязательно используйте ссылку
@HolyBlackCat, я отредактировал и опубликовал все свои объявления классов для класса LinkedList. Как вы думаете, можно ли распечатать мой связанный список, используя одну из функций выше, а также используя перегруженный оператор >> из класса Account??
Во-первых, ваши operator<<
должны принимать свои вторые параметры по константной ссылке, а не по значению, например:
ostream& operator << (ostream& out, const Account& acc)
ostream& operator << (ostream& out, const LinkedList& list)
Во-вторых, да, можно использовать оператор Account
внутри оператора LinkedList
. Вам нужно что-то эквивалентное следующему (поскольку вы не предоставили полные объявления классов):
ostream& operator << (ostream& out, const LinkedList& list) {
LinkedList::Node *cur = list.getFirst();
while (cur != NULL) {
out << cur->getData();
cur = cur->getNext();
}
return out;
}
ОБНОВЛЕНИЕ: теперь, когда вы опубликовали объявление класса LinkedList
, я вижу, что оно не предлагает ничего похожего на метод getFirst()
. У него есть методы start()
и forward()
для итерации списка, но нет метода, указывающего, когда итерация достигла конца списка.
Итак, у вас есть несколько вариантов:
getCurrent()
безопасно вызывать:class LinkedList
{
public:
...
bool hasCurrent() const;
value_type getCurrent() const;
...
};
bool LinkedList::hasCurrent() const {
return (current != NULL);
}
LinkedList::value_type LinkedList::getCurrent() const {
return current->getData();
}
ostream& operator << (ostream& out, LinkedList& list) {
list.start();
while (list.hasCurrent()) {
out << list.getCurrent();
list.forward();
}
return out;
}
getCurrent()
, чтобы он возвращал объект Account
по указателю, а не по значению, чтобы он мог возвращать указатель NULL
, когда итерация находится в конце списка:class Node
{
public:
...
value_type& getData();
...
};
LinkedList::value_type* LinkedList::getCurrent() {
if (current != NULL) {
return &(current->getData());
} else {
return NULL;
}
}
ostream& operator << (ostream& out, LinkedList& list) {
Account *cur;
list.start();
while ((cur = list.getCurrent()) != NULL) {
out << *cur;
list.forward();
}
return out;
}
LinkedList
friend
класса LinkedList
, чтобы он мог напрямую обращаться к частному члену head
:class LinkedList
{
public:
...
friend ostream& operator << (ostream& out, const LinkedList& list);
...
private:
Node* head;
...
};
ostream& operator << (ostream& out, const LinkedList& list);
ostream& operator << (ostream& out, const LinkedList& list) {
Node *cur = list.head;
while (cur != NULL) {
out << cur->getData();
cur = cur->getNext();
}
return out;
}
Привет @Remy Lebeau, спасибо за ответ. К вашему сведению, я отредактировал свой пост, включив в него объявления классов для LinkedList. Как вы думаете, можно ли распечатать мой связанный список, используя одну из функций класса, а также используя перегруженный оператор << из класса Account?
@TekaaiKaewaniti, учитывая существующие методы в классе LinkedList, нет. Я обновил свой ответ альтернативными решениями.
Нам не нужен весь ваш код, но нам нужен минимальный воспроизводимый пример. Пожалуйста, прочитайте ссылку и сделайте один.