Встроенные структуры и правильные вызовы функций - PullRequest
2 голосов
/ 30 января 2011

Вам даны две структуры. Один типа «А», другой типа «В». У типа 'B' есть структура типа 'A'. Так что-то вроде этого:

struct A {
     void print_stuff(A * a){ puts("From A"); }
};

struct B {
     A a_part;
     char * s;
     void print_stuff(B * b){
          printf("From B\n\t%s\n", b->s);
     }
};

B * B_new(char * str) {
     B * b = (B*)malloc(sizeof(struct B));
     b->s = strdup(str);
     return b; 
}

Вы хотите иметь возможность вызывать функцию print_stuff в struct B, даже с кодом, подобным этому:

A * aptr = (A*) B_new("foo");
aptr->print_stuff(aptr);

Вам НЕ разрешено использовать наследование, контейнеры C ++ или классы. Структура B ДОЛЖНА иметь a_part.

Как бы вы написали свой код так, чтобы независимо от типа указателя вызывалась правильная функция print_stuff (в этом случае, если указатель на структуру типа B был приведен к A *, как бы вы гарантировали, что вызывается функция print_stuff в B)?

Ответы [ 2 ]

3 голосов
/ 30 января 2011

Вы можете сделать print_stuff указателем на функцию, но тогда вам нужно вручную подключить его к правильной функции.Однако в этом случае вы просто реплицируете механизмы наследования C ++, так что это бессмысленно.

Объект A не может автоматически знать, где он содержится или вообще содержится.

Итак, суть в том, что просто используйте наследование C ++.

0 голосов
/ 30 января 2011

Это действительно ужасно. Но да, есть способ сделать это. Поместите поле bool в A и там же в B, чтобы указать реальный тип. Приведенный ниже код должен дать вам представление о C ++ (и в действительности не должен использоваться для каких-либо других целей).

struct A {
  bool isB;
  A()
  {
    isB=false;
  }
  void print_stuff(A * a);
};

struct B {
  bool trueB;
  A a_part;
  char * s;

  B()
  {
    isB=true;
  }

  void print_stuff(B * b){
    printf("From B\n\t%s\n", b->s);
  }
};

void A::print_stuff(A * a)
  {

    if(isB)
      {
        B* b = (B*)(this);
        b->print_stuff(b);
      }
    else
      puts("From A");
  }

B * B_new(char * str) {
  B * b = (B*)malloc(sizeof(struct B));
  b->s = strdup(str);
  b->trueB=true;
  return b;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...