有没有办法让一个函数在c++中对不同的结构(具有公共成员)进行操作

kiayqfof  于 2023-02-11  发布在  其他
关注(0)|答案(2)|浏览(150)

在传递一个void* 指针作为函数的参数之后,有没有一种方法可以指定它被转换为另一个参数的类型。

struct A{
  int key;
  char c;
}

struct B { 
  int key;
  float d;
}

有没有可能定义一个函数,

void func(void * ptr, ...){
//operate on key
}

并且在强制转换为void* 之后将指向任一结构体的指针传递给函数,并且从函数内访问键元素。
试图理解void* 的使用,结构定义是如何存储的(如何从结构定义中确定各种元素的偏移量?)以及多态性是如何在c中实现的。
我试着看看我是否能写二叉搜索树函数,可以处理任何结构的节点。

3npbholx

3npbholx1#

在将void * 指针作为参数传递给函数后,是否有方法指定将其转换为另一个参数的类型。
是也不是。
我想你希望有一些特定的东西来实现这个目的,比如一个变量来传递一个类型名,函数可以用它来执行类型转换,比如C++模板中的类型参数,或者Java泛型方法,C没有这样的东西。
当然,你可以用一个普通的整数来传递一个代码,这个代码表示要强制转换到几个预先知道的类型中的哪一个。如果你愿意,你甚至可以用一个enum来给这些代码起一个有意义的名字。例如:

enum arg_type { STRUCT_A_TYPE, STRUCT_B_TYPE };

void func(void *ptr, enum arg_type type) {
    int key = 0;

    switch (type) {
        case STRUCT_A_TYPE:
            key = ((struct A *) ptr)->key;
            break;
        case STRUCT_B_TYPE:
            key = ((struct B *) ptr)->key;
            break;
        default:
            assert(0);
    }
    // ...
}

请注意,这种方法允许访问所指向结构的 * 任何 * 成员,但如果您只想访问第一个成员,并且它在每个感兴趣的结构类型中都有相同的类型,那么您不需要知 prop 体的结构类型。在这种特殊情况下,您可以直接强制转换为成员类型:

void func(void *ptr) {
    int key = *(int *)ptr;
    // ...
}

这依赖于C语言的保证:指向任何结构的指针,经过适当的强制转换,都指向该结构的第一个成员。
试图理解void * 的使用,结构定义是如何存储的,多态性是如何在c中实现的。
太宽泛了。
C语言不提供多态性作为一种语言特性,并且C对象不携带关于其类型的信息,例如可用于分派类型特定函数的信息。当然,您可以自己实现它,但这并不是微不足道的。可用的方法包括,但不限于,

  • 将指针传递给对数据类型做正确事情的函数,标准的qsort()bsearch()函数就是这种方法的典型例子。
  • 将某种描述符对象作为每个(结构)类型的第一个成员。该成员的类型可以是结构类型本身,因此它可以传送任意复杂的数据。例如vtable。只要它是所有多态结构的第一个成员,您总是可以通过强制转换到其类型来从指向其中一个结构的指针访问它,如上所述。
  • 使用多态类型组的tagged unions(要求在构建时知道每个组中的所有类型替换). C允许你查看所有联合成员的公共初始序列中的任何成员,而不知道哪个成员实际上有值。初始序列通常会包括标记,这样你就不必单独传递它,但是它也可以包括其它信息。
  • 通过(单)继承的多态性可以通过给每个子类型一个父类型的对象作为它的第一个成员来实现,这样就允许你强制转换到(一个指向)任何超类型并得到正确的东西。
3htmauhk

3htmauhk2#

假设你有一个sort函数,它把一个函数作为参数,实现了sort的“比较”功能,那么sort就可以对任意struct的列表进行排序,方法是给它一个比较器函数,为你的特定struct实现正确的顺序。

void bubbleSort(Node* start, bool comparerFunction(void* a, void* b))

考虑以下struct定义:

typedef struct {
   int  book_id;
   char title[50];
   char author[50];
   char subject[100];
   char ISBN[13];
} Book;

这个不起眼的链表定义:

typedef struct node{
  void* item;
  struct node* next;
} Node;

它可以在item成员中存储任意的struct
因为你知道你放在链表中的成员的类型,所以你可以写一个比较器函数来做正确的事情:

bool sortByTitle(void* left, void* right) {
  Book* a = (Book*)left;
  Book* b = (Book*)right;
 
  return strcmp(a->title, b->title) > 0;
}

然后这样称呼你的同类:

bubbleSort(myList, sortByTitle);

为了完整起见,下面是bubbleSort实现:

/* Bubble sort the given linked list */
void bubbleSort(Node *start, bool greaterThan(void* a, void* b)) 
{ 
    int swapped, i; 
    Node* ptr1; 
    Node* lptr = NULL; 

    /* Checking for empty list */
    if (start == NULL) 
        return; 

    do
    { 
        swapped = 0; 
        ptr1 = start; 

        while (ptr1->next != lptr) 
        { 
            if (greaterThan(ptr1->item, ptr1->next->item))
            { 
                swap(ptr1, ptr1->next); 
                swapped = 1; 
            } 
            ptr1 = ptr1->next; 
        } 
        lptr = ptr1; 
    } 
    while (swapped); 
} 

/* function to swap data of two nodes a and b*/
void swap(Node *a, Node *b) 
{ 
    void* temp = a->item; 
    a->item = b->item; 
    b->item = temp; 
}

相关问题