2014-10-08 70 views
0

我一直在努力完成這個自我分配的項目。我的問題具體是關於「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

這大概應該是長度方法:

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()); 
    } 
} 

當,而沒有輸入功能不返回任何東西,多的同時也沒用,只執行一次(與if語句相同,這也是編譯器報告的所有警告)

+0

謝謝。這就是它。我無法告訴你我在這段時間裏一直在追趕多久。 – user3800586 2014-10-09 04:39:18