使自定义链接列表与POD一起使用

时间:2014-03-14 16:20:14

标签: c++ pointers reference linked-list

这一直困扰着我,因为我几个月前写了我的LinkedList实现。

这就是问题所在:我在一个标准库(任何类型)都不可用的环境中工作,所以我自己创建一切。

由于它是一个相当专业的环境(即OSDev),我的链表的用例很小。然而,由于我是一个懒惰的人,我想为用户空间程序使用相同的库...这将涉及扩展列表的可操作范围。

至于代码,我最后粘贴它(所以应该允许使用pastebin等,或者创建一个SO-brandded pastebin-esque的东西,或者有一些可嵌入代码的东西打开一个叠加窗口当你点击它时。)

这就是问题所在:我通常会创建LinkedList:

LinkedList<PCIDevice>* list = new LinkedList<PCIDevice>();

然后,list-&gt; Front()例如将返回PCIDevice *或指向PCIDevice的指针。这通常适用于我,因为我的大多数对象都是手动分配的新/删除。

不幸的是,如果我尝试类似

的话
LinkedList<int>* list = new LinkedList<int>();
list->InsertFront(10);

它期望InsertFront调用的int *。这让我困扰了很长时间,我该怎么做以及该怎么办?

我认为我必须按照

的方式做点什么
LinkedList<PCIDevice*>* list = new LinkedList<PCIDevice*>();

获取指向PCIDevice的指针列表...但我仍然对非指针复杂类和返回值以及方法调用参数有点困惑...所以如果有人能够解释一下这一点,它会非常感谢。

CODE:

template <class data>
class LinkedList
{
    private:
        template <typename obj>
        class SingleNode
        {
            public:
                SingleNode(obj* o = 0, SingleNode<obj>* n = 0)
                {
                    this->object = (obj*)o;
                    this->next = n;
                    this->magic = 0xBEEFBEEFBEEFBEEF;
                }

                SingleNode<obj>* next;
                obj* object;
                uint64_t magic;
        };

        uint64_t length;
        uint64_t size;
        SingleNode<data>* head;
        SingleNode<data>* tail;


        SingleNode<data>* Traverse(uint64_t i) const
        {
            SingleNode<data>* h = this->head;
            // if(i >= this->length)
            //  HALT("List index out of bounds.");

            if(this->length == 1 || i == 0)
            {
                return this->head;
            }
            else if(this->length == 2 && i == 1)
            {
                return this->tail;
            }
            for(uint64_t l = 0; l < i; l++)
            {
                h = h->next;
            }
            return h;
        }





    public:
        // this needs to be already allocated; give a head pointer.
        LinkedList()
        {
            this->head = 0;
            this->tail = 0;
            this->length = 0;
            this->size = sizeof(data);
        }
        ~LinkedList()
        {
            // delete all nodes
            for(uint64_t i = 0, m = this->length; i < m; i++)
            {
                SingleNode<data>* s = this->head;
                this->head = this->head->next;

                delete s;
            }
        }


        uint64_t Size(){ return this->length; }
        bool IsEmpty(){ return this->length == 0; }
        data* Get(uint64_t i) const
        {
            if(i >= this->length)
            {
                asm volatile("xchg %bx, %bx");
            }

            if(this->length == 1 || i == 0)
            {
                return this->head->object;
            }
            else if(i == this->length - 1)
            {
                return this->tail->object;
            }

            return this->Traverse(i)->object;
        }






        void InsertFront(data* obj)
        {
            SingleNode<data>* f = new SingleNode<data>(obj, this->head);


            if(this->IsEmpty())
            {
                this->head = f;
                this->tail = f;
            }
            else
            {
                this->head = f;
            }

            this->length++;
        }

        void InsertBack(data* obj)
        {
            SingleNode<data>* f = new SingleNode<data>(obj, 0);

            if(this->IsEmpty())
            {
                this->head = f;
            }
            else
            {
                this->tail->next = f;
            }

            this->tail = f;
            this->length++;
        }

        void AddAll(LinkedList<data>* l)
        {
            for(uint64_t i = 0; i < l->Size(); i++)
            {
                this->InsertBack(l->Get(i));
            }
        }

        data* RemoveFront()
        {
            // if(this->head == 0)
            //  HALT("Removing from empty list");

            data* obj = this->head->object;
            SingleNode<data>* old_head = this->head;

            if(this->length == 1)
            {
                this->head = 0;
                this->tail = 0;
            }
            else
            {
                this->head = this->head->next;
            }

            delete old_head;
            this->length--;
            return obj;
        }

        data* RemoveBack()
        {
            // if(this->tail == 0)
            //  HALT("Removing from empty list!");

            SingleNode<data>* old_tail = this->tail;
            data* obj = this->tail->object;


            if(this->length == 1)
            {
                this->head = 0;
                this->tail = 0;
            }
            else
            {
                SingleNode<data>* kr = this->head;
                while(kr->next != this->tail)
                    kr = kr->next;

                kr->next = 0;
                this->tail = kr;
            }

            delete old_tail;
            this->length--;
            return obj;
        }

        data* Back()
        {
            return this->tail->object;
        }

        data* Front()
        {
            return this->head->object;
        }

        void Clear()
        {
            for(uint64_t m = 0, g = this->length; m < g; m++)
            {
                this->RemoveFront();
            }
        }

        int64_t IndexOf(data* p)
        {
            for(int64_t d = 0; (uint64_t)d < this->length; d++)
            {
                if(p == this->Get((uint64_t)d))
                    return d;
            }

            return -1;
        }

        data* RemoveAt(uint64_t i)
        {
            // if(i >= this->length)
            //  HALT("List index out of bounds");

            if(i == 0)
                return this->RemoveFront();

            if(i == this->length - 1)
                return this->RemoveBack();


            data* ret = this->Get(i);
            SingleNode<data>* k = this->Traverse(i);
            SingleNode<data>* p = this->Traverse(i - 1);

            p->next = k->next;
            delete k;
            this->length--;

            return ret;
        }

        void InsertAt(uint64_t i, data* d)
        {
            if(i >= this->length)
                this->InsertBack(d);

            else if(i == 0)
                this->InsertFront(d);

            else
            {
                SingleNode<data>* p = this->Traverse(i - 1);
                SingleNode<data>* t = this->Traverse(i);
                SingleNode<data>* n = this->Traverse(i + 1);
                p->next = new SingleNode<data>(d, t);
                t->next = n;
                this->length++;
            }
        }
};

1 个答案:

答案 0 :(得分:0)

您担心的是复杂数据类型在存储时是否会像int一样运行。答案是,只要它有一个“复制构造函数”(一个接受类型ClassName&的构造函数并复制其中的所有数据),它就会完全按照你的预期行事。