Итерация по шаблону составного списка состояний

Я целую вечность пытался закончить этот самозваный проект. Мой вопрос конкретно о функции «длина», внизу — есть ли способ перебрать список без передачи параметра между одной длиной () и другой?

// File: ListCS/ListCS.hpp

#ifndef LISTCS_HPP_
#define LISTCS_HPP_

#include <iostream> // ostream.
using namespace std;

template<class T> class AcsNode; // Forward declaration.
template<class T> class NEcsNode; // Forward declaration.
template<class T> class MTcsNode; // Forward declaration.

// ========= ListCS =========
template<class T>
class ListCS {
friend class NEcsNode<T>;
friend class MTcsNode<T>;

private:
AcsNode<T> *_head;

private:
ListCS(ListCS<T> const &rhs);
// Copy constructor disabled.

ListCS(AcsNode<T> *node);
// Post: _head points to node with no allocation.

public:
ListCS();
// Post: This list is initialized to be empty.

~ListCS();
// Post: This list is deallocated.

void append(T const &data);
// Post: data is appended to this list.

void clear();
// Post: This list is cleared to the empty list.

void concat(ListCS<T> &suffix);
// Post: suffix is appended to this list.
// suffix is empty (cut concatenate, as opposed to copy concatenate).

bool contains(T const &data) const;
// Post: true is returned if data is contained in this list;
// Otherwise, false is returned.

private:
AcsNode<T> *copyHead(ListCS<T> const &rhs);
// Post: A deep copy of the head of rhs is returned.

public:
bool equals(ListCS<T> const &rhs) const;
// Post: true is returned if this list equals list rhs; Otherwise, false is returned.
// Two lists are equal if they contain the same number of equal elements in the same order.

private:
bool equalsHelper(T const &first, ListCS<T> const &rest) const;
// Post: true is returned if first equals this->first() and rest equals this->rest();
// Otherwise, false is returned.

public:
T &first();
T const &first() const;
// Pre: This list is not empty.
// Post: A reference to the first element of this list is returned.

bool isEmpty() const;
// Post: true is returned if this list is empty; otherwise, false is returned.

int length() const;
// Post: The length of this list is returned.

T const &max() const;
// Pre: This list is not empty.
// Post: The maximum element of this list is returned.

private:
T const &maxHelper(T const &val) const;
// Post: The maximum element of this list and val is returned.

public:
ListCS &operator=(ListCS<T> const &rhs);
// Post: A deep copy of rhs is returned with garbage collection.

void prepend(T const &data);
// Post: data is prepended to this list.

T remFirst();
// Pre: This list is not empty.
// Post: The first element is removed from this list and returned.

T remLast();
// Pre: This list is not empty.
// Post: The last element is removed from this list and returned.
private:
T remLastHelper(ListCS<T> &previous);
// Pre: previous.rest() is this list.
// Post: The last element of previous is removed and returned.

public:
void remove(T const &data);
// Post: If data is in this list, it is removed; Otherwise this list is unchanged.

ListCS<T> &rest();
ListCS<T> const &rest() const;
// Pre: This list is not empty.
// Post: A reference to the rest of this list is returned.

void reverse();
// Post: This list is reversed.

private:
void reverseHelper(ListCS<T> &revList);
// Post: This list is prepended to revList in reverse order, and this list is empty.

public:
void setList(ListCS<T> &list);
// Post: This list is deallocated and set to list.
// list is the empty list (cut setList, as opposed to copy setList).

void toStream(ostream &os) const;
// Post: A string representation of this list is returned.

ListCS<T> *unZip();
// Post: This is every other element of this list starting with the first.
// A pointer to a list with every other element of this list starting with the second is returned.

void zip(ListCS<T> &other);
// Post: This list is a perfect shuffle of this list and other
// starting with the first element of this.
// other is the empty list (cut zip, as opposed to copy zip).
};

// ========= AcsNode =========
template<class T>
class AcsNode {
friend class ListCS<T>;
friend class MTcsNode<T>;
friend class NEcsNode<T>;

public:
virtual ~AcsNode() {
}
// Virtual destructor necessary for subclassing.

protected:
virtual void append(ListCS<T> &owner, T const &data) = 0;
virtual void clear(ListCS<T> &owner) = 0;
virtual void concat(ListCS<T> &owner, ListCS<T> &suffix) = 0;
virtual bool contains(T const &data) const = 0;
private:
virtual AcsNode *copyHead() = 0;
protected:
virtual bool equals(ListCS<T> const &rhs) const = 0;
virtual bool equalsHelper(T const &first, ListCS<T> const &rest) const = 0;
virtual T &first() = 0;
virtual T const &first() const = 0;
virtual bool isEmpty() const = 0;
virtual int length() const = 0;
virtual T const &max() const = 0;
virtual T const &maxHelper(T const &data) const = 0;
virtual void prepend(ListCS<T> &owner, T const &data) = 0;
virtual T remFirst(ListCS<T> &owner) = 0;
virtual T remLast(ListCS<T> &owner) = 0;
virtual T remLastHelper(ListCS<T> &owner, ListCS<T> &previous) = 0;
virtual void remove(ListCS<T> &owner, T const &data) = 0;
virtual ListCS<T> &rest() = 0;
virtual ListCS<T> const &rest() const = 0;
virtual void reverse(ListCS<T> &owner) = 0;
virtual void reverseHelper(ListCS<T> &owner, ListCS<T> &revList) = 0;
virtual void setList(ListCS<T> &owner, ListCS<T> &list) = 0;
virtual void toStream(ostream &os) const = 0;
virtual void toStreamHelper(ostream &os) const = 0;
// Post: A string representation of this list is returned
// except for the leading open parenthesis "(", which is omitted.
virtual ListCS<T> *unZip() = 0;
virtual void zip(ListCS<T> &owner, ListCS<T> &other) = 0;
};

// ========= MTcsNode =========
// Empty node class.
template<class T>
class MTcsNode : public AcsNode<T> {
friend class ListCS<T>;
friend class NEcsNode<T>;

private:
MTcsNode() {
}
MTcsNode(const MTcsNode<T> &rhs); // Disabled.
MTcsNode &operator=(const MTcsNode &rhs); // Disabled for node.

protected:
void append(ListCS<T> &owner, T const &data);
void clear(ListCS<T> &owner);
void concat(ListCS<T> &owner, ListCS<T> &suffix);
bool contains(T const &data) const;
private:
AcsNode<T> *copyHead();
protected:
bool equals(ListCS<T> const &rhs) const;
bool equalsHelper(T const &first, ListCS<T> const &rest) const;
T &first();
T const &first() const;
bool isEmpty() const;
int length() const;
T const &max() const;
T const &maxHelper(T const &data) const;
void prepend(ListCS<T> &owner, T const &data);
T remFirst(ListCS<T> &owner);
T remLast(ListCS<T> &owner);
T remLastHelper(ListCS<T> &owner, ListCS<T> &previous);
void remove(ListCS<T> &owner, T const &data);
ListCS<T> &rest();
ListCS<T> const &rest() const;
void reverse(ListCS<T> &owner);
void reverseHelper(ListCS<T> &owner, ListCS<T> &revList);
void setList(ListCS<T> &owner, ListCS<T> &list);
void toStream(ostream &os) const;
void toStreamHelper(ostream &os) const;
ListCS<T> *unZip();
void zip(ListCS<T> &owner, ListCS<T> &other);
};

// ========= NEcsNode =========
template<class T>
class NEcsNode : public AcsNode<T> {
friend class ListCS<T>;
friend class MTcsNode<T>;

private:
T _data;
ListCS<T> _rest;

private:
NEcsNode(T const &data);
// Post: _data is data.

NEcsNode(T data, AcsNode<T> *node);
// Post: _data is data and _rest._head points to node.
// _rest owns node and is responsible for garbage collection.

NEcsNode(const NEcsNode<T> *rhs);
// Post: _data is rhs->_data and _rest is rhs->_rest.

NEcsNode &operator=(const NEcsNode &rhs); // Disabled for node.

protected:
void append(ListCS<T> &owner, T const &data);
void clear(ListCS<T> &owner);
void concat(ListCS<T> &owner, ListCS<T> &suffix);
bool contains(T const &data) const;
private:
AcsNode<T> *copyHead();
protected:
bool equals(ListCS<T> const &rhs) const;
bool equalsHelper(T const &first, ListCS<T> const &rest) const;
T &first();
T const &first() const;
bool isEmpty() const;
int length() const;
T const &max() const;
T const &maxHelper(T const &data) const;
void prepend(ListCS<T> &owner, T const &data);
T remFirst(ListCS<T> &owner);
T remLast(ListCS<T> &owner);
T remLastHelper(ListCS<T> &owner, ListCS<T> &previous);
void remove(ListCS<T> &owner, T const &data);
ListCS<T> &rest();
ListCS<T> const &rest() const;
void reverse(ListCS<T> &owner);
void reverseHelper(ListCS<T> &owner, ListCS<T> &revList);
void setList(ListCS<T> &owner, ListCS<T> &list);
void toStream(ostream &os) const;
void toStreamHelper(ostream &os) const;
ListCS<T> *unZip();
void zip(ListCS<T> &owner, ListCS<T> &other);
};

// ========= Constructors =========
template<class T>
ListCS<T>::ListCS() :
_head(new MTcsNode<T>()) {
}

template<class T>
ListCS<T>::ListCS(AcsNode<T> *node) :
_head(node) {
}

template<class T>
NEcsNode<T>::NEcsNode(T const &data) :
_data(data) {
}

template<class T>
NEcsNode<T>::NEcsNode(T data, AcsNode<T> *node) :
_data(data) {
_rest._head = node;
}

template<class T>
NEcsNode<T>::NEcsNode(const NEcsNode *rhs) :
_data(rhs->_data), _rest(rhs->_rest) {
}

// ========= Destructor =========
template<class T> // Recursively deletes this list.
ListCS<T>::~ListCS() {
delete _head;
}

//  Lots of function specifications here.

// ========= first =========
template<class T>
T &ListCS<T>::first() {
return _head->first();
}

template<class T>
T &MTcsNode<T>::first() {
cerr << "Precondition violated: an empty list does not have a first element." << endl;
throw -1;
}

template<class T>
T &NEcsNode<T>::first() {
return _data;
}

// ========= first const =========
template<class T>
T const &ListCS<T>::first() const {
return _head->first();
}

template<class T>
T const &MTcsNode<T>::first() const {
cerr << "Precondition violated: an empty list does not have a first element." << endl;
throw -1;
}

template<class T>
T const &NEcsNode<T>::first() const {
return _data;
}

// ========= isEmpty =========
template<class T>
bool ListCS<T>::isEmpty() const {
return _head->isEmpty();
}

template<class T>
bool MTcsNode<T>::isEmpty() const {
return true;
}

template<class T>
bool NEcsNode<T>::isEmpty() const {
return false;
}

// ========= length =========
template<class T>
int ListCS<T>::length() const {
while (!_head->isEmpty())
return (_head->length() + _head->rest().length());
}

template<class T>
int MTcsNode<T>::length() const {
return 0;
}

template<class T>
int NEcsNode<T>::length() const {
return 1;
}

// Overloaded operators, yadda yadda.

#endif

0

Решение

Это, вероятно, должен быть метод длины:

template<class T>
int ListCS<T>::length() const {
if (_head == NULL)
return 0;
return (_head->length() + _head->rest().length());
}

Линия цикла while (while (!_head->isEmpty())) ничего не делать, любой компилятор сообщит, что не пустая функция не возвращает значение по какому-либо пути. Правильно отформатированный ваш код будет таким (добавлен блок {, }, чтобы выделить проблему):

template<class T>
int ListCS<T>::length() const {
while (!_head->isEmpty()) {
return (_head->length() + _head->rest().length());
}
}

Когда значение while не введено, функция ничего не возвращает, и более того, функция while бесполезна, она выполняется только один раз (делая то же самое, что и if Скажите, об этом также сообщает компилятор со всеми предупреждениями)

0

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


По вопросам рекламы ammmcru@yandex.ru
Adblock
detector