总结工厂方法
Wrapping up factory methods
我有 2 个structs
,其构造函数接受不同数量和类型的传入参数。例如
struct A:Base
{
A(int i, char c){}
};
struct B:Base
{
B(char c){}
};
而且我还有一个工厂方法来创建这两个structs
的对象,
struct F
{
Base* Do(int i)
{
if (i==0)
{
return new A(i,'c');
}
else
{
return new B('c');
}
}
};
现在我试着像这样改善我的Factory F
struct F
{
template<int i, class X>
Base* Do();
template<class X>
Base* Do<0>()
{
return new X(i, 'c');
}
template<class X>
Base* Do<1>()
{
return new X('c');
}
};
我对这种方法唯一不感兴趣的是,如果我有很多结构A,B,C,...
,我必须编写很多专门的模板,但我只喜欢模板,不喜欢return new X(...)
。
所以我的问题是:
- 如何最小化长代码但仍使用模板?
- 如何停止返回指向基类的指针?动态分配 sux,我更喜欢工厂堆栈上的缓慢而温和的经典分配器。
- 我喜欢使用可变参数模板来表示我的
structs
' ctors 的参数。
std::any
和可变参数模板将是你的朋友。Yuu可以在std::any
中存储任何东西。any_cast
会有点问题。
请参阅以下工作代码:
#include <iostream>
#include <map>
#include <utility>
#include <any>
// Some demo classes ----------------------------------------------------------------------------------
struct Base {
Base(int d) : data(d) {};
virtual ~Base() { std::cout << "Destructor Basen"; }
virtual void print() { std::cout << "Print Basen"; }
int data{};
};
struct Child1 : public Base {
Child1(int d, std::string s) : Base(d) { std::cout << "Constructor Child1 " << d << " " << s << "n"; }
virtual ~Child1() { std::cout << "Destructor Child1n"; }
virtual void print() { std::cout << "Print Child1: " << data << "n"; }
};
struct Child2 : public Base {
Child2(int d, char c, long l) : Base(d) { std::cout << "Constructor Child2 " << d << " " << c << " " << l << "n"; }
virtual ~Child2() { std::cout << "Destructor Child2n"; }
virtual void print() { std::cout << "Print Child2: " << data << "n"; }
};
struct Child3 : public Base {
Child3(int d, long l, char c, std::string s) : Base(d) { std::cout << "Constructor Child3 " << d << " " << l << " " << c << " " << s << "n"; }
virtual ~Child3() { std::cout << "Destructor Child3n"; }
virtual void print() { std::cout << "Print Child3: " << data << "n"; }
};
using UPTRB = std::unique_ptr<Base>;
template <class Child, typename ...Args>
UPTRB createClass(Args...args) { return std::make_unique<Child>(args...); }
// The Factory ----------------------------------------------------------------------------------------
template <class Key, class Object>
class Factory
{
std::map<Key, std::any> selector;
public:
Factory() : selector() {}
Factory(std::initializer_list<std::pair<const Key, std::any>> il) : selector(il) {}
template<typename Function>
void add(Key key, Function&& someFunction) { selector[key] = std::any(someFunction); };
template <typename ... Args>
Object create(Key key, Args ... args) {
if (selector.find(key) != selector.end()) {
return std::any_cast<std::add_pointer_t<Object(Args ...)>>(selector[key])(args...);
}
else return nullptr;
}
};
int main()
{
Factory<int, UPTRB> factory{
{1, createClass<Child1, int, std::string>},
{2, createClass<Child2, int, char, long>}
};
factory.add(3, createClass<Child3, int, long, char, std::string>);
// Some test values
std::string s1(" Hello1 "); std::string s3(" Hello3 ");
int i = 1; const int ci = 1; int& ri = i; const int& cri = i; int&& rri = 1;
UPTRB b1 = factory.create(1, 1, s1);
UPTRB b2 = factory.create(2, 2, '2', 2L);
UPTRB b3 = factory.create(3, 3, 3L, '3', s3);
b1->print();
b2->print();
b3->print();
b1 = factory.create(2, 4, '4', 4L);
b1->print();
return 0;
}
相关文章:
- 如何在工厂方法中返回指向基于基础操作系统的派生类的有效指针
- 工厂方法:分配和strcpy_s的差异
- 在基类中编写工厂方法
- 从工厂方法返回的ComPtr的引用计数增加两次
- 工厂方法模式使用继承而抽象工厂模式使用组合如何
- 在C++中将返回unique_ptr和shared_ptr的两个工厂方法组合为一个
- 工厂方法中的访问冲突
- 如何模板静态工厂方法?
- 工厂方法创建的对象应该在哪里删除?
- 使用模板基类消除工厂类派生类冗余的干净方法
- 从工厂返回时,可以正确的方法来upcast superty_ptr
- 如何禁用在工厂方法之外创建/复制 obj?
- 为 STL 随机数生成器编写工厂方法
- 此工厂方法是否会导致争用条件?
- 设计模式的工厂替代方法:具有不同构造函数的类
- 如何从JSON String创建工厂方法
- unique_ptr和前向声明:编写工厂函数的正确方法
- 在工厂中使用静态方法:优点和缺点?
- C++可扩展的工厂方法
- 总结工厂方法