2016-10-08 5 views
1

Обычно объект завод создает экземпляры классов по телефонуфабрика объектов для перегруженных функций

auto world = ObjectFactory::instance()->create("MatrixTransform"); 
auto cube1 = ObjectFactory::instance()->create("Cube"); 
auto sphere = ObjectFactory::instance()->create("Sphere"); 

, которая использует карту зарегистрированных функций без параметров, таких, как этот, где класс Node является базовым классом для классы MatrixTransform, Cube и Sphere:

// Map of registered factory functions 
std::map<std::string, std::function<Node *(void)>> functionRegistry; 

Теперь я хотел бы зарегистрировать перегруженные конструкторы, принимая ограниченное число параметров (один или 2), такие как MatrixTransform(std::string objectName) или MatrixTransform(std::string objectName, glm::mat4 matrixTransform), так что я могу назвать не только

auto world = ObjectFactory::instance()->create("MatrixTransform"); 

но

auto world = ObjectFactory::instance()->create("MatrixTransform", "world"); 

и даже

auto world = ObjectFactory::instance()->create("MatrixTransform", "world", "glm::mat4())"); 

Я знаю, что можно хранить в карте функций, имеющих различные сигнатуры, смысл функции, которые имеют разные параметры и/или типы возврата, но как регистрировать функции, которые имеют не только разные подписи, но и одно и то же имя, например, перегруженные конструкторы здесь выше, учитывая, что ключ на карте должен быть уникальным и, следовательно, не может быть повторен? При необходимости может быть отправлен весь заводской код объекта. Спасибо!

+0

Вы уверены, что это не слишком сильно переработано? Есть ли * действительно * преимущество в простом создании объектов напрямую, без фабрики? Я не вижу в вашем примере, как завод бьет простой 'auto world = новый MatrixTransform (glm :: mat4())'. Я бы просто подумал об использовании 'std :: unique_ptr ' вместо 'Node *'. –

+0

@Christian Hackl У меня есть большое количество классов, разделяющих один и тот же базовый класс с конкретными экземплярами, которые необходимо создать во время выполнения, поэтому я начал с изучения шаблона фабрики объекта. И, конечно же, в конечном итоге будет использоваться 'std :: unique_ptr ' вместо 'Node *'. – LastBlow

ответ

1

Просто подумал о двух возможных решениях.

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

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

Эй, они действительно говорят, что вы должны задать вопрос, чтобы найти ответ! Мечта в коде.

+0

Приобретено для рекомендации скучных низкотехнологичных решений, которые, вероятно, будут работать достаточно хорошо :) –

+0

@ Христиан Хакл Ха, ха, ха, спасибо, ты заставил меня улыбнуться. Эй, кто-нибудь, чтобы еще больше волноваться с высокотехнологичным решением, скажем, некоторые шаблонные функции с переменным количеством аргументов? ;-))) – LastBlow

1

Вы не должны использовать карту для этого, если вы согласны использовать класс перечислимую:

#include<utility> 
#include<string> 

enum class Type { MatrixTransform, Cube, Sphere }; 

template<Type> 
struct tag {}; 

struct Factory { 
    template<Type T, typename... A> 
    static auto create(A&&... args) { 
     return create(tag<T>{}, std::forward<A>(args)...); 
    } 

private: 
    static auto create(tag<Type::MatrixTransform>) {} 
    static auto create(tag<Type::MatrixTransform>, std::string) {} 
    static auto create(tag<Type::Cube>) {} 
    static auto create(tag<Type::Sphere>) {} 
}; 

int main() { 
    Factory::create<Type::MatrixTransform>(); 
    Factory::create<Type::MatrixTransform>("foo"); 
} 

перегружающ, шаблоны и теги диспетчеризацию сделать работу здесь.


Примечание: пример требует C++ 14, но это вопрос использования правильных типов возвращаемых вместо auto и она работает также с C++ 11.

+0

Сначала хотел попробовать карты. Найдите интересный шаблон переменных аргументов, который вы используете, определенно попробуете. Большое спасибо за Вашу помощь. – LastBlow

+0

Карты @LastBlow имеют фиксированные типы. Вы хотите использовать определение различных функций в качестве значений. Это невозможно, если только вы не используете функторы. В этом случае вы просто добавляете бесполезный слой поверх решения, основанного на перегрузке. – skypjack