在C ++中实现双向链表的错误

时间:2016-04-05 21:11:58

标签: c++ class pointers c++11 linked-list

我正在尝试实现链接列表,它几乎支持所有功能,如C ++ STL链接列表。我在编译我的自定义列表时遇到错误。链接列表在temp.hpp中定义,测试人员程序为listtest.cpp

listtest.cpp: In function ‘int main(int, const char**)’:
listtest.cpp:24:12: error: ‘class mod::list<int>::iterator’ has no member named ‘get_val’
   cout<<it.get_val()<<" ";
            ^
temp.hpp: In instantiation of ‘mod::list<T>::list(const mod::list<T>&) [with T = int]’:
listtest.cpp:13:17:   required from here
temp.hpp:76:35: error: passing ‘const mod::list<int>’ as ‘this’ argument of ‘mod::link<T>* mod::list<T>::get_head() [with T = int]’ discards qualifiers [-fpermissive]
         tail = nullptr;
                                   ^
temp.hpp:77:23: error: passing ‘const mod::list<int>’ as ‘this’ argument of ‘int mod::list<T>::length() [with T = int]’ discards qualifiers [-fpermissive]
         len = 0;
                       ^
temp.hpp:86:24: error: passing ‘const mod::list<int>’ as ‘this’ argument of ‘int mod::list<T>::length() [with T = int]’ discards qualifiers [-fpermissive]

我无法弄清楚导致这些错误的原因。这是我的链接类(节点类):

template<typename T>
    class list;

    template<typename T>
    class link{
        friend class list;
        private:
            T value;
            link<T>* prev; 
            link<T>* next;
        public:
            link(){prev = next = nullptr;}
            link(const T& val){value = val; prev = next = nullptr;}
            T& get_val(){return value;}
            link<T>* get_prev(){return prev;}
            link<T>* get_next(){return next;}           
    };

这是列表类:

template<typename T>
    class list
    {
        int len;
        link<T>* head, tail;
        public:
            list();
            list(const list<T> & x);
            ~list();
            void append(const T& value);
            void append(list<T>& x);
            inline int length();
            inline bool empty();
            void cons(const T& value);  //to add a value at the start.
            void remove(const T& x);
            inline link<T>* get_head();
            inline link<T>* get_tail();
            class iterator{
                link<T>* ptr;
                public:
                    T& get_val(){return ptr->value;}
                    link<T>* get_ptr(){return ptr;}
                    iterator(){ptr = nullptr;}
                    link<T>* get_ptr{return ptr;}
                    iterator(iterator a){ptr = a.get_ptr();}
                    ~iterator(){delete[] ptr;}
                    void operator=(iterator iter){ptr = iter.get_ptr();}
                    bool operator==(iterator iter){return ptr == iter.get_ptr();}
                    void operator++(){ptr = ptr->next;}
                    void operator--(){ptr = ptr->prev;}
                    bool operator!=(iterator iter){return ptr != iter.get_ptr();}  
            };
            iterator begin(){return iterator(head);}
            iterator end(){return nullptr;};
    };

    template<typename T>
    list<T>::list(){
        head = nullptr;
        tail = nullptr;
        len = 0;
    }

    template<typename T>
    list<T>::list(const list<T>& x){
        for(list<T>::iterator it = x.begin() ; it!=x.end() ; ++it){
            append(it.get_val());    
        }
    }

    template<typename T>
    list<T>::~list(){
        link<T> *ptr = head; 
        while(ptr != nullptr){
            link<T>* ptr2 = ptr->next;
            delete ptr;
            ptr = ptr2;
        }
    }

    template<typename T>
    void list<T>::append(const T& a){
        link<T> *ptr = new link<T>;
        ptr->value = a;
        ptr->next = nullptr;
        ptr->prev = tail;
        tail->next = ptr;
        tail = ptr;
        ++len;
    }

    template<typename T>
    inline int list<T>::length(){
        return len;
    }

    template<typename T>
    inline bool list<T>::empty(){
        return len <= 0;
    }

    template<typename T>
    void list<T>::cons(const T& a){
        link<T> *ptr = new link<T>;
        ptr->value = a;
        ptr->next = head;
        ptr->prev = nullptr;
        head->prev = ptr;
        head = ptr;
        ++len;
    }

    template<typename T>
    void list<T>::remove(const T& a){
        link<T> *ptr = head;
        if(len>0 && head->value == a){
            head = head->next;
            delete ptr;
            --len;
            return;
        }
        while(ptr!=nullptr){
            if(ptr->value == a){
                ptr->prev->next = ptr->next;
                if(ptr==tail)
                    tail = ptr->prev;
                else
                    ptr->next->prev = ptr->prev;
                delete ptr;
                --len;
                return;
            }
        }
    }

    template<typename T>
    void list<T>::append(list<T>& x){
        link<T>* ptr = x.get_head();
        ptr->prev = tail;
        tail->next = ptr;
        tail = x.get_tail();
    }

    template<typename T>
    inline link<T>* list<T>::get_head(){
        return head;
    }

    template<typename T>
    inline link<T>* list<T>::get_tail(){
        return tail;
    }

这是测试程序,以防万一:

list<int> l1;
    for(int i=0;i<10;++i)
        l1.append(i*10);
    list<int> l2(l1);
    for(int i=0;i<10;++i)
        l2.append(i*15);
    list<int> l3;
    for(int i=0;i<10;++i)
        l2.append(i*3);
    l3.append(l1);
    l3.append(l2);
    l3.remove(20);
    l3.remove(30);
    for(list<int>::iterator it = l3.begin() ; it!=l3.end(); ++it)
        cout<<it.get_val()<<" ";
    cout<<"\n";

1 个答案:

答案 0 :(得分:1)

  

listtest.cpp:24:12:错误:'class mod :: list :: iterator'没有名为'get_val'的成员      COUT&LT;

您正在尝试在迭代器指向的事物上调用成员函数,但您尝试在迭代器本身上调用它。请尝试使用it->get_val代替it.get_val