В предыдущем посте «Клонирование GObject» я рассказывал про идею некоего обобщенного кода, не зависимого от конкретной задачи,
который бы сохранял объекты Gobject в файлы (типы объектов и значения
свойств) и потом воссоздавал последовательность объектов по этим файлам. Предполагалось сохранять в текстовый файл имена классов и порядок объектов, а также имена свойств объектов и их значения.
Идея красивая, но здесь мы сталкиваемся с одним ограничением системы типов GObject (ограничением вполне естественным, т.к. написан GObjecct на Си и вся поддержка ООП реализована на уровне библиотеки): чтобы создать экземпляр класса по имени класса нужно, чтобы этот класс уже был зарегистрирован в системе типов GObject. Т.е. для типа FooBar должен быть заранее вызван метод foo_bar_get_type непосредственно или опосредованно (например, через метод создания вроде foo_bar_new).
Получается: либо типы всех потенциально загружаемых из файла объектов должны быть заранее зарегистрированы, т.е. все (обязательно все) и явно (в каком-то виде) типы должны быть прописаны в коде разработчиком, либо же нужен неизящный и непортабельный механизм вроде поиска в таблице символов исполняемого файла для имени каждого подгружаемого из файла класса соответствующего метода foo_bar_get_type (см. тему на stack overflow) и вызова этого метода.
UPDATE: Найден довольно изящный и портабельный способ поиска метода foo_bar_get_type, см. Создание объектов GObject по имени типа. Часть 2.
Пример на Vala ниже иллюстрирует описанную проблему. Мы можем создать объект типа Dog по имени, т.к. выше уже создан объект типа Dog и класс зарегистрирован в системе типов. Создание объекта типа Cow же завершается неудачей (см. вывод программы после исходного кода).
Идея красивая, но здесь мы сталкиваемся с одним ограничением системы типов GObject (ограничением вполне естественным, т.к. написан GObjecct на Си и вся поддержка ООП реализована на уровне библиотеки): чтобы создать экземпляр класса по имени класса нужно, чтобы этот класс уже был зарегистрирован в системе типов GObject. Т.е. для типа FooBar должен быть заранее вызван метод foo_bar_get_type непосредственно или опосредованно (например, через метод создания вроде foo_bar_new).
Получается: либо типы всех потенциально загружаемых из файла объектов должны быть заранее зарегистрированы, т.е. все (обязательно все) и явно (в каком-то виде) типы должны быть прописаны в коде разработчиком, либо же нужен неизящный и непортабельный механизм вроде поиска в таблице символов исполняемого файла для имени каждого подгружаемого из файла класса соответствующего метода foo_bar_get_type (см. тему на stack overflow) и вызова этого метода.
UPDATE: Найден довольно изящный и портабельный способ поиска метода foo_bar_get_type, см. Создание объектов GObject по имени типа. Часть 2.
Пример на 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 коммент.:
Подписаться на:
Комментарии к сообщению (Atom)