错误c2953:类模板已经定义

时间:2022-11-05 20:41:40

I'm not sure why I'm getting this error class template has already been defined. The prof asked us to write a DLinkedOrderedList.template.h, Node.template.h, and Iterator.template.h. We're initially given DLinkedOrderedList.h. The error is only in DLinkedOrderedList.template.h and I'm not sure how to fix it so far:

我不确定为什么我得到这个错误类模板已经被定义。教授让我们写一个DLinkedOrderedList.template。h,Node.template。h,Iterator.template.h。我们最初DLinkedOrderedList.h。该错误仅出现在DLinkedOrderedList.template中。h和我不知道到目前为止该怎么解决:

DLinkedOrderedList.template.h

DLinkedOrderedList.template.h

//#include "DLinkedOrderedList.h"

template <class Item, class Order=IsLess>
class DLinkedOrderedList {
public: 

/**
 * Construct an empty list.
 */
DLinkedOrderedList(): m_head(NULL), m_tail(NULL), m_size(0);

/**
 * Make a copy of a list.
 */
DLinkedOrderedList(DLinkedOrderedList<Item, Order> const& copy){
    //copy constructor; 
    *m_head = new Node(*copy.m_head); 
    *m_tail = new Node(*copy.m_tail); 

    m_size = copy.m_size; 
};

/**
 * Destruct a list. Delete all dynamically allocated nodes.
 */
~DLinkedOrderedList(){
    Node * here = m_head, * nextNode;

    while ( here != NULL ) {
        nextNode = here->next;
        delete here;
        here = nextNode;
    }   
};

/**
 * Return the current list size. O(1).
 */
unsigned int size() const{
    return m_size; 
};

/**
 * Answer: Is the list empty? O(1).
 */
bool isEmpty() const{
    return (m_size == 0); 
};

/**
 * Get an iterator to the "beginning" or "off the ending" of this list.
 * Default to a forward iterator. Note that the "beginning" of the list for
 * a backward iterator is the tail of the list. Both are O(1).
 */
Iterator begin(Direction direction = FORWARD){return Iterator(m_head); };
Iterator end(Direction direction = FORWARD) {return Iterator(m_tail); }; //or return Iterator(NULL)

/**
 * Insert an item into the correct location in the list according to the
 * ordering defined by our templated Order class. If Order::compare(a, b) is
 * true, then a must come before b in an ordered list. Return a forward
 * iterator pointing to the inserted value. Ordering of duplicate items
 * values does not matter, but each duplicate value should be included
 * exactly in the list. E.g.,
 *
 *     Inserting 2 into list: 1 <--> 2 <--> 3
 *     results in: 1 <--> 2 <--> 2 <--> 3
 *     It doesn't matter which "2 node" is the inserted node.
 *
 * This method should be O(n).
 */
Iterator insert(Item item){
    //Node nodeItem; 
    //Iterator iteratorItem; 

    for (Iterator k = begin(); k != end(); k++){

        if (Order::compare(item, *k )){
            Iterator j = k-1; 
            Iterator l = k+1; 

            Node* here = k.m_ptr; 


        }
    }

};

/**
 * Remove a single "item"-valued item from the list and return true.
 * If no such item is found, return false. O(n).
 */
bool remove(Item item){
    //return true;
};

/**
 * Remove the specific node that "itr" refers to, and return the node's
 * value. "itr" should be adjusted to refer to the item in the "++ position"
 * with respect to the removed node (see comment under Iterator's "kill"
 * method for a detailed description). Note that this may be NULL! O(1).
 *
 * PRECONDITION: Iterator should be pointing at a valid position in the
 * list.
 */
Item remove(Iterator& itr){

};

/**
 * Remove all "item"-valued items from the list and return a count of the
 * number of such items found and removed. O(n).
 */
unsigned int removeAll(Item item){};


};

DLinkedOrderedList.h

DLinkedOrderedList.h

    #pragma once

/**
 * YOU SHOULD NOT MODIFY ANY CODE IN THIS FILE.
 *
 * Comments in this file provide details on how to implement your assignment.
 */

/**
 * StandardFunctors.h provides IsLess, the default Order for a
 * DLinkedOrderedList.
 */
#include "StandardFunctors.h"

/**
 * Direction of traversal for iterators.
 */
enum Direction {FORWARD=1, BACKWARD=2};

/**
 * Class for self-ordering doubley linked list. YOU SHOULD NOT MODIFY ANYTHING
 * "INSIDE" THIS CLASS! Instead, add your own implementations of the class
 * interface to the three files that you will create -- the ones that are
 * included below: DLinkedOrderedList.template.h, Node.template.h, and
 * Iterator.template.h.
 */
template <class Item, class Order=IsLess>
class DLinkedOrderedList {
private:
    /**
     * Private class for list nodes. Node objects are dynamically allocated
     * and freed in the appropriate constructors/operators/methods of the
     * DLinkedOrderedList class.
     */
    class Node {
    public:
        /**
         * Construct a node containing val, with next = _next and prev = _prev.
         */
        Node(Item val = Item(), Node* _next = NULL, Node* _prev = NULL);

        /**
         * Public members giving DLinkedOrderedList and Iterator (see class
         * below) direct access to nodes' data.
         */
        Item  value;
        Node* next;
        Node* prev;

     };

public:
    /**
     * Public iterator class wraps node pointers and supports minimum set.
     * of operators for iterating forward and backward. Iterators store whether
     * or not they are "forward iterators" or "backward iterators".
    * Backward iterators have inverted "operator++" and "operator--" behaviour;
     * i.e., the go to the previous node in the list using "++" and go the next
     * node in the list with "--".
     */
    class Iterator {
    private:
        /**
         * A pointer to the node that this iterator refers to.
         */
        Node* m_node;

        /**
         * A reference to the list that this iterator is "iterating over".
         */
        DLinkedOrderedList<Item, Order>& m_list;

        /**
         * Defines "forward" or "backward" traversal iterator (see defnition of
         * type Direction at the top of this file).
         */
        Direction m_direction;

        /**
         * INVARIANT: m_node is EITHER an element of lst OR NULL.
         */

    public:
        /**
         * Construct an Iterator from a pointer to a Node, a reference to the
         * list, and a direction. Default to a forward iterator.
         *
         * PRECONDTION: ptr is EITHER an element of list OR NULL.
         */
        Iterator(
            Node* const node,
            DLinkedOrderedList<Item, Order>& list,
            Direction direction = FORWARD);

    /**
     * Increment an iterator; i.e., go to the "next node" according to
     * the value of m_direction. I.e.,  "++" operator on forward
     * iterators follows the NEXT pointer of the node; "++" operator on
     * backward iterators follows the PREVIOUS pointer of the node.
     *
     * PRECONDTION: m_node is non-NULL.
     */
    Iterator& operator++();


    /**
     * Decrement an iterator; i.e., go to the "previous node" according to
     * the value of m_direction. I.e.,  "--" operator on forward
     * iterators follows the PREVIOUS pointer of the node; "--" operator on
     * backward iterators follows the NEXT pointer of the node.
     *
     * PRECONDTION: m_node is non-NULL.
     */
    Iterator& operator--();

    /**
     * Answer the question: Does "this" NOT point to the same node as "b"?
     */
    bool operator!=(Iterator const& b) const;

    /**
     * Overridden dereference operator* below allows to access item value
     * contained in this iterator's node.
     *
     * HINT: "const'ness" of this function indicates that none of "this"'s
     * members are changed while the function is running. It does not mean
     * that the returned Item's reference is "const", which WOULD be a
     * problem if we want to change item's value as in expression like:
     *
     *     (*myItr) = 3; // Assuming MyItr is an iterator object.
     *
     * We DON'T have this problem because the returned Item& is NOT const.
     * Expressions such as this are a valid, useful way of changing list
     * item values.
     *
     * PRECONDTION: m_node is non-NULL.
     */
    Item& operator*() const;

    /**
     * Delete/remove an item from the position correpsonding to the
     * iterator) inside the list and returns the item value; the iterator
     * should point to the "++ position" in the list according to the
     * value of m_direction. I.e., forward iterators should
     * point to the NEXT node after the deleted node; backward iterators
     * should point to the PREVIOUS node prior to the deleted node. Note
     * that the node in the "++ position" may be NULL.
     *
     * HINT 1: You can implement this really easily by exploiting one of
     * DLinkedOrderedList's removal methods...
     *
     * HINT 2: When following HINT 1, let DLinkedOrderedList's removal method
     * do the "++"-ing; make sure you don't increment twice by mistake!
     */
    Item kill();

    /**
     * Make DLinkedOrderedList a friend. This gives it access protected and
     * private members.
     *
     * HINT 3: Access to m_node greatly simplifies the implementation of
     * DLinkedOrderedList's "Item remove(Iterator& itr)" (see below).
     */
    friend class DLinkedOrderedList;
};

/**
 * Construct an empty list.
 */
DLinkedOrderedList();

/**
 * Make a copy of a list.
 */
DLinkedOrderedList(DLinkedOrderedList<Item, Order> const& copy);

/**
 * Destruct a list. Delete all dynamically allocated nodes.
 */
~DLinkedOrderedList();

/**
 * Return the current list size. O(1).
 */
unsigned int size() const;

/**
 * Answer: Is the list empty? O(1).
 */
bool isEmpty() const;

/**
 * Get an iterator to the "beginning" or "off the ending" of this list.
 * Default to a forward iterator. Note that the "beginning" of the list for
 * a backward iterator is the tail of the list. Both are O(1).
 */
Iterator begin(Direction direction = FORWARD);
Iterator end(Direction direction = FORWARD);

/**
 * Insert an item into the correct location in the list according to the
 * ordering defined by our templated Order class. If Order::compare(a, b) is
 * true, then a must come before b in an ordered list. Return a forward
 * iterator pointing to the inserted value. Ordering of duplicate items
 * values does not matter, but each duplicate value should be included
 * exactly in the list. E.g.,
 *
 *     Inserting 2 into list: 1 <--> 2 <--> 3
 *     results in: 1 <--> 2 <--> 2 <--> 3
 *     It doesn't matter which "2 node" is the inserted node.
 *
 * This method should be O(n).
 */
Iterator insert(Item item);

/**
 * Remove a single "item"-valued item from the list and return true.
 * If no such item is found, return false. O(n).
 */
bool remove(Item item);

/**
 * Remove the specific node that "itr" refers to, and return the node's
 * value. "itr" should be adjusted to refer to the item in the "++ position"
 * with respect to the removed node (see comment under Iterator's "kill"
 * method for a detailed description). Note that this may be NULL! O(1).
 *
 * PRECONDITION: Iterator should be pointing at a valid position in the
 * list.
 */
Item remove(Iterator& itr);

/**
 * Remove all "item"-valued items from the list and return a count of the
 * number of such items found and removed. O(n).
 */
unsigned int removeAll(Item item);

private:
    /**
     * Standard list data structure members: head of the list, tail of the list,
     * size of the list.
     */
    Node* m_head;
    Node* m_tail;
    unsigned int m_size;
};


/**
 * CREATE THE THREE FILES #include'd BELOW AND INSERT YOUR CODE THERE!
 * To make debugging easier, include these files in your Visual Studio project.
 */
#include "DLinkedOrderedList.template.h"
#include "Node.template.h"
#include "Iterator.template.h"

2 个解决方案

#1


3  

The class template has already been defined in the "main" header "DLinkedOrderedList.h", so don't define it again in the "template" header. Just define the member functions, e.g.

类模板已经在"main" header "DLinkedOrderedList中定义。h,所以不要在“模板”标题中再次定义它。只需定义成员函数,例如

template <class Item, class Order>
DLinkedOrderedList::DLinkedOrderedList() : 
    m_head(NULL), m_tail(NULL), m_size(0)
{}

#2


1  

Every header file should have a header guard:

每个头文件都应该有头文件保护:

#ifndef THIS_HEADER_H // Use a unique identifier for every file.
#define THIS_HEADER_H

// All contents of the header. Nothing goes before #ifndef or after #endif.

#endif

The lack of such a thing will cause a header included from different files to be processed twice, leading to literally all kinds of duplicate definition errors.

缺少这样的东西会导致包含在不同文件中的头两次被处理,从而导致各种重复的定义错误。

The example DLinkedOrderedList.h uses a nonstandard facility to solve the same issue, #pragma once, but this is not a generally accepted practice.

DLinkedOrderedList的例子。h使用一个非标准的工具来解决同一个问题#pragma一次,但是这并不是一个普遍接受的实践。

Furthermore, headers should all go at the top of a file, never at the bottom as your professor did. The canonical way to write a header (or any kind of program) is to state prerequisites, then implement additional functionality. There is no reason to diverge from the pattern here. You should be including DLinkedOrderedList.h, not the other way around. (In this case it is beyond your control, but just FYI.)

此外,标题应该放在文件的顶部,而不是像教授那样放在底部。编写头(或任何类型的程序)的标准方法是声明先决条件,然后实现附加功能。没有理由偏离这里的模式。你应该包括DLinkedOrderedList。不是反过来的。(在这种情况下,它超出了你的控制范围,只是FYI。)

#1


3  

The class template has already been defined in the "main" header "DLinkedOrderedList.h", so don't define it again in the "template" header. Just define the member functions, e.g.

类模板已经在"main" header "DLinkedOrderedList中定义。h,所以不要在“模板”标题中再次定义它。只需定义成员函数,例如

template <class Item, class Order>
DLinkedOrderedList::DLinkedOrderedList() : 
    m_head(NULL), m_tail(NULL), m_size(0)
{}

#2


1  

Every header file should have a header guard:

每个头文件都应该有头文件保护:

#ifndef THIS_HEADER_H // Use a unique identifier for every file.
#define THIS_HEADER_H

// All contents of the header. Nothing goes before #ifndef or after #endif.

#endif

The lack of such a thing will cause a header included from different files to be processed twice, leading to literally all kinds of duplicate definition errors.

缺少这样的东西会导致包含在不同文件中的头两次被处理,从而导致各种重复的定义错误。

The example DLinkedOrderedList.h uses a nonstandard facility to solve the same issue, #pragma once, but this is not a generally accepted practice.

DLinkedOrderedList的例子。h使用一个非标准的工具来解决同一个问题#pragma一次,但是这并不是一个普遍接受的实践。

Furthermore, headers should all go at the top of a file, never at the bottom as your professor did. The canonical way to write a header (or any kind of program) is to state prerequisites, then implement additional functionality. There is no reason to diverge from the pattern here. You should be including DLinkedOrderedList.h, not the other way around. (In this case it is beyond your control, but just FYI.)

此外,标题应该放在文件的顶部,而不是像教授那样放在底部。编写头(或任何类型的程序)的标准方法是声明先决条件,然后实现附加功能。没有理由偏离这里的模式。你应该包括DLinkedOrderedList。不是反过来的。(在这种情况下,它超出了你的控制范围,只是FYI。)