迭代复合状态列表模式

时间:2014-10-08 20:45:12

标签: c++ list state composite

我已经尝试了很长时间才能完成这个自我指定的项目。我的问题是关于"长度"函数,在底部 - 是否有一种方法来迭代列表而不在一个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

1 个答案:

答案 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语句相同,编译器也报告所有警告)