我已经尝试了很长时间才能完成这个自我指定的项目。我的问题是关于"长度"函数,在底部 - 是否有一种方法来迭代列表而不在一个length()和另一个length()之间传递参数?
// 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 :(得分:0)
这可能应该是长度法:
template<class T>
int ListCS<T>::length() const {
if (_head == NULL)
return 0;
return (_head->length() + _head->rest().length());
}
while循环行(while (!_head->isEmpty())
)不执行任何操作,任何编译器都会报告非void函数在某些路径中不返回值。正确格式化您的代码将为(添加块{
,}
,以突出显示问题):
template<class T>
int ListCS<T>::length() const {
while (!_head->isEmpty()) {
return (_head->length() + _head->rest().length());
}
}
当没有输入while时,函数不会返回任何内容,而while则无用,它只执行一次(与if
语句相同,编译器也报告所有警告)