问题描述
我正在使用C,并且不允许使用C ++。目前,我正在尝试在C语言中实现某种程度的OOP。我目前正在尝试实现多态性和继承。
我大部分时间都在阅读如何通过使用函数指针来实现我的目标。我正在尝试打印两个结构的成员变量,如下所示:
Recordobject.h
typedef struct SuperRecordobject
{
char *Id;
char *date;
char *cases;
char *deaths;
void (*ptrPrintRecord)(char *id,char *date,char *cases,char *deaths,char *names_fr,char *names_en);
} SuperRecord;
typedef struct ChildRecordobject
{
SuperRecord super;
char *names_fr;
char *names_en;
} ChildRecord;
Recordobject.c
#include <stdio.h>
#include "Recordobject.h"
void ptrPrintRecord(char *id,char *names_en)
{
//char *record;
printf(" %s | %s | %s | %s | %s | %s\n",id,date,cases,deaths,names_fr,names_en);
//return record;
}
DataLayer.c
#include <stdio.h>
#include <string.h>
#include "Recordobject.h"
/* more code here */
void(*fun_ptr)(char*,char*,char*) = &record.super.ptrPrintRecord; //
(*fun_ptr)(record.super.Id,record.super.date,record.super.cases,record.super.deaths,record.names_fr,record.names_en);
/* more code here */
但是,当我编译(使用GCC)时,会收到此警告,导致崩溃。
warning: initialization of 'void (*)(char *,char *,char *)' from incompatible pointer type 'void (**)(char *,char *)' [-Wincompatible-pointer-types]
62 | void(*fun_ptr)(char*,char*) = &record.super.ptrPrintRecord;
我已经在其他文件中运行了一些其他指针函数来弄乱并对其进行测试,而我唯一能想到的是它可能与C中字符串的工作方式有关。 / p>
解决方法
尝试分配的函数指针中有多余的&
。结构的ptrPrintRecord
成员已经已经是正确类型的函数指针,因此您不需要&
-可以给出地址该指针的strong>。
只需使用:
void(*fun_ptr)(char*,char*,char*) = record.super.ptrPrintRecord; // No &
作为旁注,您将ptrPrintRecord
用作该成员(函数指针),还将用作实际函数的名称(具有相同的“签名”)可能会导致一些问题,甚至进一步。
此外,您需要先将该成员(指针)初始化为有效的函数地址,然后再将其复制到您随后调用的对象中(以及该结构的其他成员)。这是一个小的main
(使用您的其他代码),可以正常工作:
int main()
{
ChildRecord record;
record.super.ptrPrintRecord = ptrPrintRecord; // See my note about the name clash!
record.super.Id = "ID";
record.super.date = "today";
record.super.cases = "cases";
record.super.deaths = "deaths";
void(*fun_ptr)(char*,char*) = record.super.ptrPrintRecord; //
// To call the pointed-to function,we can just use the pointer name:
fun_ptr(record.super.Id,record.super.date,record.super.cases,record.super.deaths,record.names_fr,record.names_en);
return 0;
}