这一直困扰着我,因为我几个月前写了我的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++;
}
}
};
答案 0 :(得分:0)
您担心的是复杂数据类型在存储时是否会像int
一样运行。答案是,只要它有一个“复制构造函数”(一个接受类型ClassName&
的构造函数并复制其中的所有数据),它就会完全按照你的预期行事。