TalismanChet
@TalismanChet
Лицо зла

Имитация ООП в C, где ошибка?

Я написал имитацию ООП в С, но код не работает.
Можете помочь, почему?

#pragma clang diagnostic ignored "-Wint-conversion"

#include <stdio.h>

typedef struct point {
    int x;
    int y;
    char* (*tochar)();
} point;

int *_p_d_s;
static int _point_tochar_size;
char* _point_tochar()
{
    int here = 0;
    int int_size = sizeof(here);
    int self_addr = here-2*int_size;
    point *self = self_addr;
    char* ret;
    sprintf(ret, "point X%d, Y%d", self->x, self->y);
    return ret;
};
int *_p_d_e;

//point constructor
point Point(int x, int y)
{
    point ret = {x, y};
    _point_tochar_size = _p_d_e-_p_d_s;
    return ret;
};

int main(int argc, char** argv)
{
    point test = Point(5, 10);
    printf("%s", test.tochar());
    return 0;
};
  • Вопрос задан
  • 222 просмотра
Решения вопроса 2
wataru
@wataru
Разработчик на С++, экс-олимпиадник.
int self_addr = here-2*int_size;
point *self = self_addr;


Это что вообще такое?! Объясните, что вы пытались тут сделать вообще.

Для имитации ООП надо в структуре иметь указатель на функцию, который надо инициализировать, внезапно, указателем на функцию, например, вот так:
ret.tochar = &ToCharFunc.

Сама функция должна помимо обычных параметров еще и принимать указатель на объект, с которым вы хотите работать.
Ответ написан
@res2001
Developer, ex-admin
Ну как минимум вы ничем не инициализируете test.tochar в "конструкторе", но используете этот указатель в printf, это вызывает вылет программы без вызова _point_tochar.

Вычисление адреса объекта (self) вы так не сделаете. Я в принципе могу догадаться, что вы пытались сделать, но это выполнено явно не правильно. И это даже может дать правильный результат, если правильно реализовать. Но любое изменение в стеке приведет к тому, что "формулу" придется переделывать. А стек меняется при каждом вызове и возврате из функции, при каждом объявлении локальной переменной, т.е. очень часто.
Так что адрес объекта передавайте явно в функцию.

В "Экстремальный Си" описывается подход к ООП на Си.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
includedlibrary
@includedlibrary
Нужно self явно в функцию передавать, а не арифметикой указателей заниматься.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы