首页 > 解决方案 > 是否有可能构建一个足够通用的队列,允许它将任何数据类型存储为对象?

问题描述

本质上,我试图实现的是一个通用enqueue( Queue *queue, void *key )功能。我希望这个队列存储任何数据类型。这就是我构建队列的方式:

typedef struct Node {
    void *key;
    struct Node *next;
}Node;

typedef struct Queue {
    Node *front;
    Node *back;
}Queue;

Queue* initializeQueue() {
    Queue *queue = (Queue*) malloc(sizeof(Queue));
    queue->front = NULL;
    queue->back = NULL;
    return queue;
}

void enqueue( Queue *queue, void *key ) {
    Node *tempRef = (Node*) malloc(sizeof(Node)); // Inserted Node will be in the back of Queue
    tempRef->key = key;
    tempRef->next = NULL;
    if ( queue->front == NULL && queue->back == NULL ){ // When the Queue is empty
        queue->front = tempRef;
        queue->back = tempRef;
    }
    else { // When the Queue is non-empty
        queue->back->next = tempRef; 
        queue->back = tempRef;
    }
}

但事实是,这种实现是错误的,因为我将参数 void 指针存储为对象,并且它指向的地址依赖于外部数据类型(例如,像 char),这不是预期的。例如,以下代码会将地址 &key 链接到队列中的对象:

char key = '-';
enqueue(queue, &key );

所以理想情况下,我想在我的队列中存储不是地址的对象。但是,如何将任意数据类型存储为 Node 结构中的对象?显然,void*正如我上面所说,利用不是解决方案,那么甚至有可能找到解决我的问题的方法吗?

提前致谢

标签: cpointersvoid-pointers

解决方案


是否有可能构建一个足够通用的队列,允许它将任何数据类型存储为对象?

是的。

考虑如何fwrite()知道如何写入任何对象的内容:
通过接收对象的地址及其大小。

Node需要保存对象副本的地址及其大小。

typedef struct Node {
    struct Node *next;
    // void *key;
    void *data;
    size_t size;
} Node;

enqueue()需要扩大...

// void enqueue( Queue *queue, void *key )
void enqueue(Queue *queue, const void *data, size_t size)
// Address of the object --------------^^^^
// Size of the object ------------------------------^^^^

...然后为副本分配空间,然后复制它。

Node *tempRef = malloc(sizeof *tempRef);
tempRef->data = malloc(size);
if (tempRef->data == NULL) {
  free(tempRef);
  return true; // fail
}
memcpy(tempRef->data, data, size);
tempRef->size = size;
tempRef->next = NULL;
...
return false; // success

如果对象中有指针...

只有指针被复制,而不是它们指向的数据。

然而在这一点上,类型丢失了

数据被存储,但类型丢失。

出队时,可用的只是入队数据的地址和大小,而不是其类型。

出队可以假设该类型 - 如果此代码具有一组用于该类型的包装函数,这就足够了......

... 或者 ....

还通过某种枚举保存类型(来自一组有限类型)。研究_Generic


如果整个队列中的类型相同或每个节点可能不同,则会出现代码简化/复杂性。

祝你好运。


推荐阅读