С Новым годом! Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.79
ILJON
7 / 7 / 0
Регистрация: 18.10.2008
Сообщений: 49
#1

Factory Method - C++

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

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

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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
14.10.2009, 20:11
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Factory Method (C++):

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

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

Use the method of Erathosfen - C++
Give N (2&lt;=N&lt;=10000) number,find and output the prime numbers between 2 and given N. Prime number is the number that can be divided by 1...

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

Template Method Pattern - C++
Задание называется Template Method Pattern. из параграфа полиморфизм. Вообщем суть задания создать функцию Print() которая бы правильным...

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

4
Nick Alte
Эксперт С++
1642 / 1014 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
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
Rififi
2360 / 1053 / 44
Регистрация: 03.05.2009
Сообщений: 2,656
14.10.2009, 21:28 #3
ILJON,
перед тем как лезть в паттерны, сначала разберись с тремя основными китами C++ (два из них используются в этот примере - наследование и полиморфизм)
0
ILJON
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
Nick Alte
Эксперт С++
1642 / 1014 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
16.10.2009, 21:15 #5
верно
1
16.10.2009, 21:15
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
16.10.2009, 21:15
Привет! Вот еще темы с ответами:

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

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

std::sort(iterator, iterator, method) подскажите как исправить - C++
Уважаемые Знатоки!!! Вашему вниманию предоставляю код: #include &quot;stdafx.h&quot; #include &lt;vector&gt; #include &lt;algorithm&gt; class...

Ошибки underfined reference to parentClass::method и unerfined reference to vtable при линковке - C++
При сборке компилятор выдает ошибки underfined reference to и unerfined reference to vtable. Есть базовый класс, два наследуемых от него и...


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

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.