Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 11.10.2012, 04:23   #1
Rangok
Пользователь
 
Регистрация: 30.07.2012
Сообщений: 13
По умолчанию Передача аргументов в фабрику объектов

Здраствуйте. У меня следующая задача: необходимо написать приложение, в котором пользователь может создавать различные графические фигуры. При создании конкретной фигуры пользователь задает ее размеры. Для удобства создания объектов и добавления новых классов фигур я хочу использовать фабрику объектов. При этом все графические объекты объединяются абстрактным классом и регистрируются в фабрике. Рассмотрим пример из трех фигур: Rectangle, Triangle и Circle, которые наследуют абстрактный класс Shape2d:
Код:
#include <iostream>
using namespace std;

typedef pair<double,double> Point2d;
ostream& operator <<(ostream& stream,const Point2d& point)
{
stream<<"("<<point.first<<", "<<point.first<<")";
return stream;
}

class Shape2d
{
public:
virtual void GetInformation()=0;
virtual ~Shape2d(){}
};

class Rectangle:public Shape2d
{
public:
Rectangle(const Point2d& leftBottomPoint,
const double& width,const double& height):
leftBottomPoint_(leftBottomPoint),width_(width),height_(height)
{}
void GetInformation()
{
cout<<"\nПрямоугольник высотой "<<height_<<", шириной "<<width_
<<"левый нижний угол которого находится в точке с координатами "
<<leftBottomPoint_;
}
virtual ~Rectangle(){}
protected:
Point2d leftBottomPoint_;
double width_;
double height_;
};

class Triangle:public Shape2d
{
public:
Triangle(const Point2d& p1,const Point2d& p2,const Point2d& p3):
point1_(p1),point2_(p2),point3_(p3)
{}
void GetInformation()
{
cout<<"\nТреугольник, с вершинами в точках :"<<point1_<<"; "<<point2_
<<" и "<<point3_<<".";
}
virtual ~Triangle(){}
protected:
Point2d point1_;
Point2d point2_;
Point2d point3_;
};

class Circle:public Shape2d
{
public:
Circle(const Point2d& center,const double& radius):
center_(center),radius_(radius)
{}
void GetInformation()
{
cout<<"\nКруг, с центром в точке :"<<center_<<" и радиусом "<<radius_
<<".";
}
virtual ~Circle(){}
protected:
Point2d center_;
double radius_;
};
Как видно из описания классов, для их создания требуются аргументы, причем для каждого класса типы и количество аргументов разные.
Как в таком случае зарегестрировать эти классы в одной фабрике, чтобы можно было cоздавать объекты, передавая список необходимых аргументов, различный для каждого класса?
Каким образом можно реализовать подобные конструкции?
Код:
Shape2d* pShape;
pShape=ShapeFactory.Create("Circle",(2,2),5);
pShape=ShapeFactory.Create("Triangle",(2,2),(0,0),(5,5));
pShape=ShapeFactory.Create("Rectangle",(2,2),5,10);
Rangok вне форума Ответить с цитированием
Старый 11.10.2012, 10:45   #2
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,493
По умолчанию

Никак... ну не совсем никак, но сложно и ненужно.
Но можно сделать фабрику с различными Create методами - CreateCircle, CreateTriangle и т.д.
waleri вне форума Ответить с цитированием
Старый 11.10.2012, 15:07   #3
Rangok
Пользователь
 
Регистрация: 30.07.2012
Сообщений: 13
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
ну не совсем никак
"Не совсем никак" это как?
Цитата:
Сообщение от waleri Посмотреть сообщение
Но можно сделать фабрику с различными Create методами - CreateCircle, CreateTriangle и т.д.
Тогда для добавления нового класса в фабрику необходимо будет изменять код самой фабрики, добавляя в нее новый метод. Вроде как, именно от этих проблем должна избавлять фабрика.
Rangok вне форума Ответить с цитированием
Старый 11.10.2012, 15:55   #4
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,493
По умолчанию

Ну например вы делаете union из структур для каждого типа объекта. При
создавании объекта передаем едакий универсальный параметр. Там внутри можно
даже тип указывать.
Правда при добавлении нового типа надо будет добавлять новые структуры но что делать...

А вообщето может стоит вынести инициализацию в полученный объект. Создаете объект по имени типа, потом делаете dynamic_cast до нужного интерфейса и вызываете нужные методы с нужными параметрами.
waleri вне форума Ответить с цитированием
Старый 11.10.2012, 16:37   #5
sVasilich
Форумчанин
 
Аватар для sVasilich
 
Регистрация: 16.12.2009
Сообщений: 224
По умолчанию

Цитата:
Сообщение от Rangok Посмотреть сообщение
Тогда для добавления нового класса в фабрику необходимо будет изменять код самой фабрики, добавляя в нее новый метод. Вроде как, именно от этих проблем должна избавлять фабрика.
Вообще, если я правильно понял идею шаблона "Абстрактная фабрика", вам нужно создать абстрактный класс AbstractShapeFactory, а от него наследовать конкретные фабрики (CircleFactory, TriangleFactory), которые буду реализовывать метод Create();

Остаётся вопрос как передать различные аргументы. Можно воспользоваться контейнерами stl. Тем же вектором: аргументы всё равно все типа int. Но тогда нет гарантии что пользователь введёт правильные аргументы...
Люди бывают 10 типов: те, кто понимают двоичную систему счисления, и те, кто не понимают...
sVasilich вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Передача в функцию переменного кол-ва аргументов РАЗНЫХ типов stranger84 Общие вопросы C/C++ 17 18.07.2012 15:38
Передача аргументов в функции по ссылке skanku Общие вопросы C/C++ 2 11.01.2012 21:24
Передача в функцию неограниченного количества аргументов pronaks Общие вопросы C/C++ 4 13.12.2011 22:54
Передача аргументов в функцию. C++ Kholmansky Помощь студентам 2 15.09.2011 01:02
Передача аргументов программе на Си, как реализовать? cympak Общие вопросы C/C++ 6 02.03.2010 19:49