【问题标题】:C++ Templated Class Invalid Use of Incomplete ClassC++模板类无效使用不完整类
【发布时间】:2012-12-24 15:42:09
【问题描述】:

尝试学习 C++。我的代码中出现错误,如下行:

class LinkedList : public LinkedList<T> {

错误提示:

不完整类型'class的无效使用 链表, std::allocator > >' 类的声明 链表, std::allocator > >'

谁能指出我做错了什么?这是完整的代码。

#ifndef LINKEDLIST_HPP
#define LINKEDLIST_HPP


#include <iostream>

using namespace std;

template <class T>
class LinkedList : public LinkedList<T> {

    private:
        // a ListNode consists of the item and a pointer to the next ListNode
        struct ListNode {
            T data;
            ListNode *next;
        };
        int size; //Size of the list
        ListNode *head; //the beginning of the list

    public:
        LinkedList(); // default oonstructor
        ~LinkedList(); // destructor
        virtual bool isEmpty ();
        virtual int  getLength ();
        virtual void insert (int pos, T item);
        virtual T    remove (int pos);
        virtual T    retrieve (int pos);

        //helper methods
        LinkedList(LinkedList &copyList); //copy constructor
        ListNode *find (int pos) const; // internal find function
};

//default constructor
template <class T>
LinkedList<T>::LinkedList() {
    size = 0;
    head = NULL;
}

//destructor
template <class T>
LinkedList<T>::~LinkedList() {
    //loop through each node, and delete it
    ListNode* current = head;
    while (current != NULL) {
        ListNode* next = current->next;
        delete current;
        current = next;
    }
    head = NULL; // set head node to back to null
}

//copy constructor
template <class T>
LinkedList<T>::LinkedList(LinkedList& copyList) {
    size = copyList.size;

    // if copyList is empty
    if (copyList.head == NULL)
        head = NULL;

    else {
        //create a new head
        head = new ListNode;
        head->data = copyList.head->data;

        //create a new list
        ListNode *newPtr = head; // start at the head
        // iterate through rest of list to be copied
        for (ListNode *copyPtr = copyList.head->next; copyPtr != NULL; copyPtr = copyPtr->next) {
            newPtr->next = new ListNode;
            newPtr->data = copyPtr->data;
        }
        //make last ListNode's next point to NULL
        newPtr->next = NULL;
    }
}

template <class T>
bool LinkedList<T>::isEmpty() {
    if (size == 0)
        return true;
    return false;
}

template <class T>
int LinkedList<T>::getLength() {
    return size;
}

// used in other methods to find a given index
template <class T>
LinkedList<T>::ListNode LinkedList<T>::find(int pos) const {

    // check that pos is in bound of LinkedList
    if ((pos < 1) || pos > getLength()) {
        cout << "Find position of out bounds" << endl;
        return NULL;
    } else { //search through ListNodes
        ListNode *temp = head; // start at the head
        for (int i = 1; i < pos; ++i)
            temp = temp->next;
        return temp;
    }
}


template <class T>
T LinkedList<T>::retrieve(int pos) {
    T tempData; // to hold retrieved data
    try {
        if ((pos < 1) || (pos > getLength())) {
            cout << "Retrieve request outside LinkedList's bounds" << endl;
            return NULL;
        }
        else { //traverse list
            ListNode *temp = find(pos);
            tempData = temp->data;
            return tempData;
        }
    } catch (int e) {
        cout << "Could not retrieve position " << pos << endl;
    }
}

template <class T>
void LinkedList<T>::insert(int pos, T item) {

    //check bounds
    if ((pos < 1) || (pos > getLength() +1))
        cout << "Must insert at a position between 1 and getLength() + 1" << endl;

    else {
        try {
            //create new ListNode
            ListNode *temp = new ListNode;
            temp->data = item;

            //if the new item is at the first position
            if (pos == 1) {
                temp->next = head;
                head = temp;
            }
            else {
                ListNode *prev = find(pos - 1);
                temp->next = prev->next;
                prev->next = temp;
            }
            //increment size
            ++size;

        } catch (int e) {
            cout << "Error inserting " << item << " at position " << pos << endl;
        }
    }
}

template <class T>
T LinkedList<T>::remove(int pos) {

    //check bounds
    if ((pos < 1) || (pos > getLength()))
        cout << "Must remove a position between 1 and getLength()" << endl;

    else {
        try {

            ListNode *temp; //to hold shifted node

            //if node to be deleted is first node
            if (pos == 1) {
                temp = head;
                head = head->next;
            }
            //for anything but the head
            //write over the node before the pos'th index
            else {
                ListNode *prev = find(pos - 1);
                temp = prev->next;
                prev->next = temp->next;
            }

            //destroy temp, to free up memory
            temp->next = NULL;
            delete temp;

            //decrement size
            --size;

        } catch (int e) {
            cout << "Error removing item from position " << pos << endl;
        }
    }


}

#endif  /* LINKEDLIST_HPP */

【问题讨论】:

    标签: c++ templates


    【解决方案1】:
    template <class T>
    class LinkedList : public LinkedList<T> {
    

    这没有意义。是这样的:

    class A : public A
    

    这对你有意义吗?具体如何?

    您派生的类不存在,而是在您派生时定义了它,因此编译器不知道基础应该是什么。在从基类派生之前,编译器需要知道基类的完整定义。

    【讨论】:

    • 知道了。估计没有意义。我从一本书中提取了一些代码:猜我拿的太多了。我应该如何声明Ts的类?
    • @Adam_G:这是不同的问题。我认为您应该创建另一个主题,并在发布之前正确地提出问题。
    【解决方案2】:

    纳瓦兹给出了正确的答案。

    只是提供一些离题的信息:

    使你的析构函数虚拟化(即使从模板化容器继承不是很 c++ 的东西)。

    在它所属的地方使用 const :

    LinkedList(const LinkedList &copyList); //copy constructor
    virtual bool isEmpty () const;
    // etc.
    

    显然,在现实生活中,您会使用像 std::list 这样的 stl 容器;)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-12-23
      • 2019-06-21
      • 1970-01-01
      • 2017-10-24
      • 1970-01-01
      • 2011-11-04
      相关资源
      最近更新 更多