Я работаю с C, и мне не разрешено использовать C ++. В настоящее время я пытаюсь реализовать некоторый уровень ООП на C. В настоящее время я пытаюсь реализовать полиморфизм и наследование.

Я потратил большую часть дня на чтение того, как мои цели достигаются с помощью указателей на функции. Я пытаюсь распечатать переменные-члены обеих структур, как показано здесь:

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;

Я определил функцию ptrPrintRecord в этом файле:

RecordObject.c

#include <stdio.h>
#include "RecordObject.h"
void ptrPrintRecord(char *id, char *date, char *cases, char *deaths, char *names_fr, 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*,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 *, char *, char *, char *)' from incompatible pointer type 'void (**)(char *, char *, char *, char *, char *, char *)' [-Wincompatible-pointer-types]
   62 |        void(*fun_ptr)(char*,char*,char*,char*,char*,char*) = &record.super.ptrPrintRecord;

Я запускал некоторые другие функции указателей в других файлах, чтобы повозиться и протестировать их, и единственное, что я могу придумать относительно того, что здесь происходит, - это, возможно, какое-то отношение к тому, как строки работают в C?

0
ComradeSpaceMan 10 Ноя 2020 в 01:52

1 ответ

Лучший ответ

У вас есть посторонний & в вашей попытке присвоения указателя функции. Член ptrPrintRecord вашей структуры уже является указателем на функцию правильного типа, поэтому вам не нужен & - который дал бы адрес этого указателя.

Просто используйте:

void(*fun_ptr)(char*, char*, char*, 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*, char*, char*, 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;
}
1
Adrian Mole 9 Ноя 2020 в 23:15