Как получить адрес указателя в функции, которая вызывается через этот указатель - PullRequest
0 голосов
/ 16 апреля 2019

Я прочитал эту статью , но она не отвечает на мой вопрос.

file: hero.h

typedef struct {
    int     id;
    void    (*setId)();
    int     (*getId)();
} Hero, *HeroPtr;

файл: hero.c

#include "hero.h"

static void setId(int id);

Hero obj = {
     .setId = setId,
     .getId = getId,
};

void setId(int id) {
    HeroPtr hero_obj = 0x0; //TODO how get address: hero_obj1 (1 > ) OR 
                            //                      hero_obj2 (2 > )
    hero_obj->id = id;
}

void getId() {
    HeroPtr hero_obj = 0x0; //TODO how get address: hero_obj1 (1 > ) OR 
                            //                      hero_obj2 (2 > )
    return hero_obj->id;
}

файл: main.c

#include "hero.h"

int main() {
    Hero hero_obj1, hero_obj2;
//1 >
    hero_obj1->setId(1);
//2 >
    hero_obj2->setId(2);
    return 0;
}

Ответы [ 2 ]

0 голосов
/ 17 апреля 2019

Вы можете сделать эквивалент того, что C ++ делает за кулисами.

file: hero.h

typedef struct hero {
    int     id;
    void    (*setId)(struct hero*, int);
    int     (*getId)(struct hero*);
} Hero, *HeroPtr;

void constructHero(HeroPtr this);

file: hero.c

#include "hero.h"                                       
static void setId(HeroPtr this, int id);                
static int getId(HeroPtr this);                         

Hero initObj = {                                        
 .setId = &setId,                                   
 .getId = &getId,                                   
};                                                      

void constructHero(HeroPtr this)                        
{                                                       
    *this = initObj;                                
}                                                       

void setId(HeroPtr this, int id) {                      
    HeroPtr hero_obj = this;                            
    hero_obj->id = id;                              
}                                                       

int getId(HeroPtr this) {                               
    HeroPtr hero_obj = this;                            

    return hero_obj->id;                                
}                                                       

file: main.c

#include "hero.h"
#include "stdio.h"

int main() {
    Hero hero1;
    Hero hero2;
    HeroPtr hero_obj1=&hero1;
    HeroPtr hero_obj2=&hero2;
    constructHero(hero_obj1);
    constructHero(hero_obj2);
    hero_obj1->setId(hero_obj1, 1);
    hero_obj2->setId(hero_obj2, 2);
    printf("hero_obj1 id = %d\n", hero_obj1->getId(hero_obj1));
    printf("hero_obj2 id = %d\n", hero_obj2->getId(hero_obj2));

    return 0;
}
0 голосов
/ 17 апреля 2019

Похоже, вы пытаетесь реализовать виртуальные функции в C, используя указатели функций. В объектно-ориентированных языках программирования, таких как C ++ или Java, такие функции или методы внутри классов имеют неявный указатель this в качестве аргумента, который скрыт. Это означает, что функция int getId() на самом деле имеет подпись int getId(Hero* this), а функция void setId(int id) на самом деле имеет форму void setId(Hero* this, int id). Как я уже сказал, в объектно-ориентированных языках программирования вы не видите и не добавляете указатель this, а также не передаете аргумент при вызове функции. Компилятор сделает это за вас. Он всегда автоматически передает указатель на экземпляр как указатель this, для которого была вызвана функция. В C, однако, эти функции не существуют. Поэтому вам нужно добавить аргумент this и передать его при вызове функции самостоятельно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...