使自定义链表与pod一起工作

Making Custom Linked List work with PODs

本文关键字:一起 工作 pod 自定义 链表      更新时间:2023-10-16

自从几个月前我写了我的LinkedList实现后,这个问题就一直困扰着我。

这就是问题所在:我工作的环境中没有标准库(任何类型的)可用,所以我必须自己创建所有内容。

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

至于代码,我把它粘贴在最后(SO真的应该允许粘贴等,或者创建一个SO品牌的粘贴式的东西,或者有一些可嵌入的代码的东西,当你点击它打开一个覆盖窗口)。

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

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

那么,list->Front()将返回PCIDevice*,或者一个指向PCIDevice的指针。这通常对我有效,因为我的大多数对象都是用new/delete手动分配的。

不幸的是,如果我尝试像

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

它期望InsertFront调用是int*类型。这个问题困扰了我很长一段时间,我该怎么做?

我想我应该按照

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

获取指向PCIDevice的指针列表。但我仍然有点困惑的非指针复杂类和返回值和方法调用参数…因此,如果有人能解释一下,我将不胜感激。

代码:

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++;
            }
        }
};

您担心的是,当您去存储它时,复杂数据类型是否会像int一样运行。答案是,只要它有一个"复制构造函数"(一个接受类型ClassName&并复制其中所有数据的构造函数),那么它将完全按照您的期望行事。