В предыдущем посте «Клонирование GObject» я рассказывал про идею некоего обобщенного кода, не зависимого от конкретной задачи, который бы сохранял объекты Gobject в файлы (типы объектов и значения свойств) и потом воссоздавал последовательность объектов по этим файлам. Предполагалось сохранять в текстовый файл имена классов и порядок объектов, а также имена свойств объектов и их значения.

Идея красивая, но здесь мы сталкиваемся с одним ограничением системы типов GObject (ограничением вполне естественным, т.к. написан GObjecct на Си и вся поддержка ООП реализована на уровне библиотеки): чтобы создать экземпляр класса по имени класса нужно, чтобы этот класс уже был зарегистрирован в системе типов GObject. Т.е. для типа FooBar должен быть заранее вызван метод foo_bar_get_type непосредственно или опосредованно (например, через метод создания вроде foo_bar_new).

Получается: либо типы всех потенциально загружаемых из файла объектов должны быть заранее зарегистрированы, т.е. все (обязательно все) и явно (в каком-то виде) типы должны быть прописаны в коде разработчиком, либо же нужен неизящный и непортабельный механизм вроде поиска в таблице символов исполняемого файла для имени каждого подгружаемого из файла класса соответствующего метода foo_bar_get_type (см. тему на stack overflow) и вызова этого метода.

Пример на Vala ниже иллюстрирует описанную проблему. Мы можем создать объект типа Dog по имени, т.к. выше уже создан объект типа Dog и класс зарегистрирован в системе типов. Создание объекта типа Cow же завершается неудачей (см. вывод программы после исходного кода).

public abstract class Animal : Object
{
  public abstract string to_string();
}

public class Cow : Animal
{
  public override string to_string()
  {
    return "I'm a cow!";
  }
}

public class Dog : Animal
{
  public override string to_string()
  {
    return "I'm a dog!";
  }
}

int main()
{
  Animal a;
  Type type;

  a = new Dog(); //< Явно создаем Dog, здесь класс и регистрируется в системе типов.
  print("1) %s\n", a.to_string());

  if((type = Type.from_name("Dog")) != 0)
  {
    a = Object.new(type) as Animal;
    print("2) %s\n", a.to_string());
  }
  else
    print("2) Failed to get type!\n");

  if((type = Type.from_name("Cow")) != 0)
  {
    a = Object.new(type) as Animal;
    print("3) %s\n", a.to_string());
  }
  else
    print("3) Failed to get type!\n");

  return 0;
}
Вывод программы:
1) I'm a dog!
2) I'm a dog!
3) Failed to get type!

0 коммент.:


 

Copyright © 2007 DamnSmallBlog. Content is licensed under Creative Commons Attribution-Noncommercial.

Design: GeckoandFly and Blogcrowds.