2013-06-20 5 views
0

Мне нужно получить новые экземпляры абстрактного типа, и две вещи, которые приходят мне на ум, - это абстрактная фабрика и клонирование умных указателей. Какой из них выглядит лучше? Фабричный метод кажется более универсальным, но слишком многословным, особенно когда абстрактные объекты вложены. Указатель клонирования более компактен, но кажется немного уродливым, потому что нам нужно создать «фиктивный» объект, используемый в качестве шаблона для создания других объектов.Клонирование умных указателей против абстрактной фабрики

class IObject { 
public: 
    virtual ~IObject() {} 
}; 

class Foo: public IObject { 
public: 
    struct Config {}; 
    explicit Foo(const Config& config): config_(config) {} 

private: 
    Config config_; 
}; 

Аннотация завод:

class IObjectFactory { 
public: 
    virtual ~IObjectFactory() {} 
    virtual std::unique_ptr<IObject> Create() const = 0; 
}; 

class FooFactory: public IObjectFactory { 
public: 
    explicit FooFactory(const Foo::Config& config): config_(config) {} 

    std::unique_ptr<IObject> Create() const { 
     return std::unique_ptr<IObject>(new Foo(config_)); 
    } 

private: 
    Foo::Config config_; 
}; 

void DoSomething(const std::shared_ptr<IObjectFactory>& factory) { 
    std::vector<std::shared_ptr<IObject>> objects; 
    for (int i = 0; i < 10; ++i) { 
     objects.push_back(factory->Create()); 
    } 
    // Do something with the created objects 
} 

int main() { 
    auto factory = std::make_shared<FooFactory>(Foo::Config()); 
    DoSomething(factory); 
} 

указатель Clone (one of the implementations):

template <typename T> class clone_ptr; // deep cloning smart pointer 

void DoSomething(const clone_ptr<IObject>& object) { 
    std::vector<clone_ptr<IObject>> objects; 
    for (int i = 0; i < 10; ++i) { 
     objects.push_back(object); 
    } 
    // Do something with the created objects 
} 

int main() { 
    clone_ptr<IObject> object(new Foo(Foo::Config())); 
    DoSomething(object); 
} 

ответ

0

Чем проще всего сделать, это то, что вам haven't предоставляется в качестве опции. Добавьте к базовому объекту виртуальную функцию clone и используйте ее для клонирования объектов.

Я не совсем понимаю, как оба подхода, которые вы предоставили, справлялись с одной и той же проблемой ... подход указателя сложный, чтобы получить право, умный указатель должен будет сделать magic для отслеживания, который является реальным типом который хранится внутри, чтобы иметь возможность клонировать (думаю, магия как тип стирание). Завод, как показано выше, требует, чтобы вы знали тип, который вы хотите использовать клон.

Смежные вопросы