2012-01-13 10 views
7

Возможно, есть простой способ обойти это, чего я не вижу, поэтому, надеюсь, кто-нибудь может объяснить это мне.Flyweights с Boost и внешними источниками данных

Скажем, у меня есть класс:

class A { 
public: 
    const double parameter; 
    const std::string name; 
    const std:: string fileName; 

    A(const double parameter, const std::string name, const std::string fileName) : 
     parameter(parameter), name(name), fileName(fileName) {}; 
}; 

и генератор для этого класса:

class AReader { 
public: 
    ifstream dataFile; 
    AReader(const std::string filename); 
    A* readObject(const std::string objectName); 
}; 

Я хотел бы использовать boost::flyweight обрабатывать эти A объекты, потому что будет потенциально миллионы ссылок на них, и в действительности они содержат много данных. Они будут хешированы на name и fileName вместе.

Что мне нужно для выполнения этой работы? Мне нужен boost::flyweight, чтобы позвонить AReader.readObject и хэш/сохранить полученный класс A.

Должен ли стать AReader стать полным заводом и использовать его как изготовленную на заказ фабрику? Или можно использовать завод по умолчанию в мухи и каким-то образом использовать AReader для генерации экземпляров A (в отличие от реализации всего шаблона хранения, требуемого на заводе), возможно, сделав пример аргументом в чем-то в мухи? Или можно получить общедоступные переменные const (т. Е. Когда они установлены, они не меняются) из внешнего источника данных, не прибегая к второму классу?

Редактировать

Я также открыт для других предложений не используя Boost. Я могу, конечно, написать свою собственную реализацию мухи или любой другой шаблон, если он лучше подходит. Но если я могу использовать то, что уже существует, это было бы лучше. Что бы ни уменьшало количество кода, которое мне нужно написать, потому что, как всегда, короткие сроки.

ответ

1

Я не использовал Boost :: flyweight, но с точки зрения его, по крайней мере, ключ должен быть Assignable (в дополнение к EqualityComparable и Hashable). С вашим const членами, которые вы вводите, явно неAssignable. По внешнему виду, вам не нужно делать это Assignable, если у вас есть ключ-экстрактор. При использовании ключевого экстрактора только ключ должен быть Assignable.

+0

Это то, что нужно сделать, чтобы получить 'A' в мухи (ключ-экстрактор, а не назначаемый), но это единственный способ использовать вспомогательный класс, который генерирует' A' для сделать его полномасштабной фабрикой, которая будет использоваться мухой (для реализации хранения и других методов)? – tpg2114

0

Основной способ использования мухи в вашем случае - для readObject вернуть мухи. Внутренне, readObject создает совершенно новый объект, и когда вы создаете соответствующий мухомодный объект, он затем проверяет, находится ли объект уже в хранилище мухи. Если это так, он потеряет ваш новый объект и вернет мухи, ссылающиеся на объект в магазине. Если нет, он добавляет новый объект в свой пул.

Теперь это должно быть тривиально для реализации, но в зависимости от вашего варианта использования может быть неэффективным. Для улучшения производительности вы можете использовать функциональность key_value, которая позволяет вам ссылаться на объекты через свой ключ и создавать их только в том случае, если они еще не присутствуют в магазине.

0

Хотя key_value Вес, как кажется, соответствует счету, казалось бы, есть небольшая заминка. Вы должны иметь возможность построить вес key_value, используя только один параметр типа ключа (key_value flyweights).Поэтому, чтобы заставить его работать с нужным ключом (имя файла + имя), вам придется упаковать эти 2 поля в один (tuple? Даже не уверенный, что это сработает.)

Предполагая, что вы заинтересованы в получении большинство с наименьшим количеством работы, почему не только Flyweight строки в вашем классе, как показано в Flyweight Basics?

Это объекты A не хешированы так, как вы хотите, но строки легко переносятся в весе, и эти выглядят, чтобы быть вашими проблемами с памятью. (если это не упрощает)