Снижение иерархии с неполиморфными типами - PullRequest
3 голосов
/ 31 января 2011

Это строго в C.

Скажем, у вас есть одна базовая структура и 2 других производных структуры. Эти производные структуры не являются производными в классическом смысле (то есть: A: B), скорее, они содержат только структуры базового типа. Поэтому, если структура A является основой, а B является одной из 2 производных структур, B будет иметь член типа A. Например:

struct A {
     // blah blah...
};

struct B {
     A part_a;
     // more stuff...
}

struct C {
     A part_a;
     // SO MUCH STUFF
}

Скажем, у вас есть функция A_downcast_B, что-то вроде этого:

B * A_downcast_B(A * a)
{
     // downcast the A* here somehow
}

Вы хотите, чтобы эта функция возвращала 0 или -1, если 'a' не удалось успешно преобразовать в структуру типа B. Так, например, если бы «производная» структура типа C имела указатель на нее типа A*, и этот указатель был передан этой функции, функция вернула бы 0, -1 или null .

Есть ли способ сделать это? Я думал об этом уже несколько часов, и это поставило меня в тупик.

1 Ответ

8 голосов
/ 31 января 2011

Невозможно обойтись без встраивания некоторой информации о типах среды выполнения в struct A.Например, вы можете хранить указатель на какую-то информацию о типе, и вы должны инициализировать это всякий раз, когда создаете какую-либо «производную» структуру.

struct RTTI {
  const char *typename;
  // etc.
};

struct A {
  const RTTI *rtti;
  // rest of A
};

struct B {
  A part_a;
  ...
};

const RTTI RTTI_B = {"B"};

struct C {
  A part_a;
  ...
};

const RTTI RTTI_C = {"C"};

void make_B(B *b)
{
  b->part_a.rtti = &RTTI_B;
  // make the rest of B
}

void make_C(C *c)
{
  c->part_a.rtti = &RTTI_C;
  // make the rest of C
}

B * A_downcast_B(A * a)
{
   return (a->rtti == &RTTI_B) ? (B*)a : NULL;
}

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

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