Как установить элементы данных производного класса продукта в шаблоне проектирования?
class Factory
{
public:
product* Create(int type)
{
switch (type)
{
case 1:
return new product1;
break;
case 2:
return new product2;
break;
}
}
};
class product
{
int a;
public :
product();
product(int a);
void seta (int a);
};
class product1:public product
{
int b;
public:
product1();
product1(int a,int b):product(a), b(b) {}
void setb (int b);
};
class product2:public product
{
int c;
public:
product2();
product2(int a, int c):product(a), c(c) {}
void setc (int c);
};
\\ client code
void main()
{
Factory f;
product* p = f.create(1); // product1 created
p->seta(2);
// now how to set value b of product1
}
Примечание: если я нажму p на p1, тогда не будет смысла использовать фабрику. Следовательно, не знаю, как его использовать.
EDIT: метод набора добавлен для продукта, продукта1, продукта2. Как установить значение для b в главном, если product1 создан с использованием фабрики?
В идеале b
будет задано Factory
во время create
. Есть ли причина, почему это невозможно?
В противном случае вам, вероятно, придется установить b
через virtual
метод для Product
. Предпочтительно посредством virtual
метода, который имеет смысл в контексте всех Product
.
Откуда берется значение b
? Например, скажем, что значение исходит из файла, может иметь смысл иметь виртуальный метод Product::setThingsFromFile(string file)
. Переопределите этот virtual
метод в Product1
чтобы установить b
из файла.
Это может быть немного перебор, но вы можете рассмотреть использование шаблона посетителя и установить b
в методе ConcreteVisitor::visit(Product1& product)
.
В качестве последнего средства вы можете добавить virtual void Product::setB(int b)
который является не-оператором для большинства Product
и только на самом деле делает что-либо для Product1
но это не очень хорошая идея в целом и является хорошим способом создания беспорядка Product
.
Помните, что точкой Factory является то, что клиентский код не должен знать, с каким Product
он работает, поэтому, если ему нужно знать, что он имеет Product1
для установки b
то с помощью Factory не так много смысла.
product
может иметь некоторые (чистые) виртуальные методы. Эффект вызова таких методов зависит от динамического типа объекта, не требуется нисходящее.
product1
иproduct2
не имеют конструкторов с нулевым параметром. Просто дайте им конструкторы, которые принимают столько параметров, сколько у них есть членов для инициализации, и вызовите эти конструкторы изFactory::Create
. Из вашего описания не совсем понятно, подумал, гдеFactory
должна принимать фактические значения дляa
,b
иc
.