Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.83/18: Рейтинг темы: голосов - 18, средняя оценка - 4.83
7 / 7 / 0
Регистрация: 18.10.2008
Сообщений: 49
1

Factory Method

14.10.2009, 20:11. Показов 3306. Ответов 4
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Начал разбираться с фабричным методом нашел пример в интеренете и некоторые моменты кода не понимым :]
прошу помощи в поиснении кода некоторых моментах кода, пометил эти места коментом //

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include<iostream>
#include<string>
using namespace std;
 
// "Product"
class Product{
public:
    virtual string getName() = 0; // [U]vitrual что нам дает? [/U]
};
 
// "ConcreteProductA"
class ConcreteProductA : public Product{
public:
    string getName(){
        return "ConcreteProductA";
    }
};
 
// "ConcreteProductB"
class ConcreteProductB : public Product{
public:
    string getName(){
        return "ConcreteProductB";
    }
};
 
// "Creator"
class Creator{
public: 
    virtual Product* FactoryMethod() = 0;
};
 
// "ConcreteCreatorA"
class ConcreteCreatorA : public Creator{
public:
    Product* FactoryMethod() {
        return new ConcreteProductA();
    }
};
 
// "ConcreteCreatorB"
class ConcreteCreatorB : public Creator{
public: 
    Product* FactoryMethod() {
        return new ConcreteProductB();
    }
};
 
int main(){
    const int size = 2;
    // An array of creators
    Creator* creators[size];
      creators[0] = new ConcreteCreatorA();
      creators[1] = new ConcreteCreatorB();    
 
 
    // Iterate over creators and create products
    for(int i=0;i<size;i++){
    Product* product = creators[i]->FactoryMethod(); // [U]что то запутался в этойстрочке [/U]
                                                                                 // [U]как правильно ее трактовать ? :[[[/U]
        cout<<product->getName()<<endl;
        delete product;
    }
 
    int a;
    cin>>a;
 
    for(int i=0;i<size;i++){
        delete creators[i];
    }
    return 0;
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
14.10.2009, 20:11
Ответы с готовыми решениями:

Курсовая работа Паттерн «Абстрактная фабрика/Abstract Factory»
Задание на курсовой проект: Паттерн «Абстрактная фабрика/Abstract Factory». Реализация 2-х/3-х...

Abstract Factory, переделка примера из книги Александреску с variadic templetes
Александреску (&quot;Современное проектирование на С++&quot;), 9 глава. Там автор приводит очень интересный...

Use the method of Erathosfen
Give N (2&lt;=N&lt;=10000) number,find and output the prime numbers between 2 and given N. Prime number...

Get-Method не работает
class Stack { private: myString *st; int size; int index; public: Stack(int);...

4
Эксперт С++
1674 / 1046 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
14.10.2009, 21:17 2
Класс Product - абстрактный класс, определяющий интерфейс. Абстрактный - значит, создавать экземпляры этого класса нельзя, создавать можно только его потомков. virtual обозначает функцию, которая вызывается через таблицу. =0 означает, что виртуальный метод не определён (это и делает класс абстрактным). В объекте хранится информация о таких функциях, позволяющая осуществлять их вызов (указатель на таблицу виртуальных методов, но сейчас это неважно). Чтобы потомок такого класса можно было создать, в нём должны быть определены все занулённые в предках виртуальные функции, тогда такой класс станет конкретным и можно будет создавать его объекты.
В твоём случае можно создавать объекты классов ConcreteProductA и ConcreteProductB, а обращаться к этим объектам через указатель на класс Product. Обрати внимание - фактические типы объектов разные, а обращение к ним происходит через указатель одного и того же типа. Это называется полиморфизм - возможность одинаковым образом работать с объектами разных типов. При этом благодаря тому самому virtual при обращении к getName будет происходить обращение именно к той функции, которую переопределил класс-потомок. Аналогичным образом определён класс-создатель для продуктов и его потомки - создатели для продуктов A и B. В функции main создаётся массив из 2 указателей на создателя-предка, но создаётся не сам предок Creator, а два его разных потомка. Поскольку они оба произошли от Creator, указатели на эти объекты легко преобразуются к типу указателя на предка. Затем по очереди у каждого из этих объектов вызывается виртуальный метод, создающий продукт. Поскольку объекты разные, а метод виртуальный, вызывается сначала ConcreteCreatorA::FactoryMethod(), а потом ConcreteCreatorB::FactoryMethod(). В результате на первом шаге локальному указателю на Product присваивается адрес на свежесозданного ConcreteProductA, а на втором шаге - ещё более свеженького ConcreteProductB. Оба указателя неявно приводятся к типу Product. Затем происходит вызов виртуального метода getName, а раз он виртуальный, то вызывается метод, который определён в реальном классе объекта. Таким образом, сначала печатается "ConcreteProductA", а затем - "ConcreteProductB".
Общий подход таков: допустим, у тебя есть набор различных, но родственных по смыслу объектов. Ты определяешь некоторый абстрактный класс-интерфейс. В нём ты определяешь ТОЛЬКО виртуальные методы, соответствующие общим для всех объектов операциям. Делаешь их чистыми (т.е. =0) и не определяешь. Делаешь свои конкретные классы потомками этого интерфейса и определяешь там нужные для них данные, дополнительные операции, и определяешь ВСЕ операции интерфейса так, чтобы они правильно работали именно с этим классом. Дальше ты можешь собрать в одну коллекцию объекты разного типа и размера, пользуясь указателями на их общий предок. Ты можешь пройтись по всей коллекции циклом, вызывая какую-то из операций, определённых в интерфейсе. При этом за счёт волшебного слова virtual для каждого объекта из коллекции будет автоматически вызываться операция, определённая в его классе.
1
MCSD: APP BUILDER
8794 / 1073 / 104
Регистрация: 17.06.2006
Сообщений: 12,602
14.10.2009, 21:28 3
ILJON,
перед тем как лезть в паттерны, сначала разберись с тремя основными китами C++ (два из них используются в этот примере - наследование и полиморфизм)
0
7 / 7 / 0
Регистрация: 18.10.2008
Сообщений: 49
14.10.2009, 21:52  [ТС] 4
верно ли я понял
Product* product = creators[i]->FactoryMethod();

Product* product // декларируем ссылку на класс Product
creators[i]->FactoryMethod(); // вызываем функцию FactoryMethod() и в зависимости от того что у нас в creators[i] путь нашь идет дальше в ConcreteCreatorA (или ConcreteCreatorB) и уже от туда у нас возвращеается ConcreteProductA() (или ConcreteProductB())

cout<<product->getName(); // а здесь уже исходя из того что нам вернулось ConcreteProductA или ConcreteProductB мы и выбираем в какой getName нам идти

верно я понял? :]
0
Эксперт С++
1674 / 1046 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
16.10.2009, 21:15 5
верно
1
16.10.2009, 21:15
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
16.10.2009, 21:15
Помогаю со студенческими работами здесь

Template Method Pattern
Задание называется Template Method Pattern. из параграфа полиморфизм. Вообщем суть задания...

Template Method Pattern
Где можно об этом почитать на русском нормальный материал ? Template Method Pattern

Допустима ли запись вида void method(T *& member)? (ссылка на указатель)
Есть структура struct FamilyMember { int age; std::string name; FamilyMember(int...

<method name> is not a member of <class> при любом типе возвращаемого значения, кроме int
Проблема в следующем, есть класс описанный в .h файле, методы класса описаны в .cpp, при компиляции...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru