C++ 如何实现包含整数和空指针的双链接列表?
我正在尝试实现我自己版本的通用数据结构,以改进我的编码。我有一个作业,它需要一个双链接列表,可以保存C++ 如何实现包含整数和空指针的双链接列表?,c++,linked-list,void-pointers,C++,Linked List,Void Pointers,我正在尝试实现我自己版本的通用数据结构,以改进我的编码。我有一个作业,它需要一个双链接列表,可以保存int和void指针,void*data。My struct有两种成员类型,一种用于int,另一种用于void* struct Node { int data; void* pntData; Node* next; Node* previous; }; class LL { private: Node* head; Node* tail; i
int
和void指针,void*data
。My struct有两种成员类型,一种用于int
,另一种用于void*
struct Node {
int data;
void* pntData;
Node* next;
Node* previous;
};
class LL {
private:
Node* head;
Node* tail;
int size;
public:
LL();
void insert_front(int data);
void insert_front(void* data);//overloaded for void pointer data types
void printLL();//removed unrelated methods
};
这是我的节点结构和双链表类。我已经能够编写所有处理int
的方法。我的困惑在于将一个空指针作为参数,并将其添加到具有int
值的同一个链表中
我知道空指针是一个可以指向任何类型数据的指针,但我不知道应该如何将空指针作为参数,并将其添加到使用此构造函数初始化的同一个链表中:
LL::LL() {
head = nullptr;
tail = nullptr;
size = 0;
}
这里是我的append函数,在这里我想到了重载,如果参数是指针,那么数据将作为void*pntData
添加到我的类变量中。如果参数是int,那么数据将作为int
添加到我的类变量中
void LL::insert_front(int data) {
Node* temp = new Node();
if (head == nullptr) {
head = temp;
temp->previous = nullptr;
temp->next = nullptr;
temp->data = data;
tail = temp;
}
else {
temp->previous = nullptr;
temp->next = head;
temp->data = data;
head->previous = temp;
head = temp;
}
size++;
}
void LL::insert_front(void* data) {
Node* temp = new Node();
if (head == nullptr) {
head = temp;
temp->previous = nullptr;
temp->next = nullptr;
temp->pntData = data;
tail = temp;
}
else {
temp->previous = nullptr;
temp->next = head;
temp->pntData = data;
head->previous = temp;
head = temp;
}
size++;
}
问题可能出在我的printLL()
函数中,它可能需要一个if/else来确定是否需要打印int
,或者是否需要打印void*pntData
请给我指出正确的方向。根据您的注释,您希望
printLL()
打印void*
指针指向的对象
这是不可能的。void*
指针没有关于它所指向的类型的信息,因此无法取消对指针的引用
如果要执行此操作,则需要在节点
中存储指向处理程序函数的附加指针,printLL()
将调用每个节点
打印其void*
。然后,您需要在指针类型上创建insert.*
函数模板,以便为提供的类型找出要存储的正确函数指针,即:
struct Node {
int data;
void* pntData;
Node* next;
Node* previous;
void(*print)(void*) = nullptr; // Initialize with null pointer to indicate that no `void*` is stored.
};
//...
template<typename T>
void LL::insert_front(T* data) {
Node* temp = new Node();
//...
temp->print = [](void* ptr){
if(ptr != nullptr)
std::cout << *static_cast<T*>(ptr);
else
// What to do if we stored a null pointer for `void*`
};
//...
}
//...
void LL::printLL() {
//...
if(node->print != nullptr)
node->print(node->pntData);
//...
}
struct节点{
int数据;
void*pntData;
节点*下一步;
节点*先前;
void(*print)(void*)=nullptr;//使用空指针初始化以指示未存储“void*”。
};
//...
模板
void LL::insert_front(T*数据){
Node*temp=新节点();
//...
临时->打印=[](无效*ptr){
如果(ptr!=nullptr)
std::cout print!=nullptr)
节点->打印(节点->pntData);
//...
}
我有一种感觉,这不是该练习打算让你做的,但正如我在评论中所说的,它首先对我来说没有意义。正确的方向因为你将是一本C++的书,它涵盖了现代C++;特别是关于如何使用<代码> STD::变体< /Cord>模板,它完成了你要问的内容。它将使程序变得简单得多,就像只需要一个代码>插入式前/ <代码>(),而不是痛苦的代码复制。阅读后,经过一些练习,您应该能够完成此“在线作业”。祝你好运!我认为在值类型上设置链接列表模板可能更有教育意义,即编写一个包含
节点
类的泛型链接列表
。然后,你可以使用包含整数的链接列表,和(分别)void指针。这似乎不是一个好的练习。如果不存储指针指向的类型的信息,则在容器中存储void*
指针是没有意义的,但这是一项相当困难的任务,实际上您只需使用std::variant
或(很少)std::any
改为类型泛型容器的元素类型。您希望看到什么printLL()
如果元素是一个void*
,则打印?指针中存储的地址或指针指向的对象?是否希望列表接受空指针作为有效值来存储void*
?虽然我同意您的意见,但这是我必须遵循的赋值。因此,我无法将空指针存储在节点结构中不同时存储类型?列表应包含整数和指针。您可以根据需要添加其他类型。包括以下成员函数:void insert_front(int data);void insert_front(void*data);void insert_rear(int data);void insert_rear(void*data);int remove_front_i();void*remove_front_p();int remove_real_i();void*remove_real_p();int empty();使用动态内存。使用“新建”插入时分配内存的指令和删除时返回内存的delete指令。@Suede和printLL
的规范是什么?这是指令,您的答案看起来非常有用。我将在晚饭后不久返回。非常感谢您的帮助,空指针让我感到困惑在Suede C++中几乎不需要< C++ >代码> java >。这在C.是很常见的,这就是为什么练习是如此混乱的。它不是C++是如何正常编写的。如果你不需要<代码> PrtLL</代码>,如果该列表只需要用它给出的相同指针类型来工作,那么你就不需要我在答案中所写的内容。t是printl
函数(或需要该类型的任何其他函数)如果你不需要这个函数,那么你可以只存储一个附加的<代码>布尔O/S>来指示你是否存储了一个<代码> int <代码>或<代码> Value*/Cuff>。@ SueDe这是很不幸的。在某个点上,把C++作为C的扩展是有意义的,但是现代C++的习惯风格是非常不同的。来自C的ENT,如果从一开始就教C或者实际的C++,那就更好了,因为两者混合使一切都变得不必要的复杂,就像你在这里看到的一样。