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

Visual C++

Войти
Регистрация
Восстановить пароль
 
Kronos0041
2 / 2 / 0
Регистрация: 18.03.2014
Сообщений: 146
#1

Паттерн фабрика + синглтон + посетитель - Visual C++

03.04.2016, 21:40. Просмотров 295. Ответов 2
Метки нет (Все метки)

Вообщем столкнулся с проблемой линковки, но уже 10 раз все пересмотрел, и перечитал как реализуется паттерн посетитель, никак ни могу понять в чем ошибки(около 100). Паттерн фабрика + синглтон получилось реализовать, но вот после посетителя все рушится.
И вот такая странная ошибка линковки у меня вызывает панику:
error C2664: "void CVisitor::visit(CCircle &)": невозможно преобразовать аргумент 1 из "CTriangle" в "CRectangle &"
triangle.cpp(22)


При реализации паттерна посетитель опирался на такие источники:
1) http://cpp-reference.ru/patterns/behavioral-patterns/visitor/
2) https://ru.wikipedia.org/wiki/%D0%9F...D%D0%B8%D1%8F)

Идея программы реализовать классы фигур таких как Треугольник, Прямоугольник и Окружность, используя паттерны приведенные выше.

Весь код выкладывать не буду, так как много, выложу реализацию одной фигуры, так как все фигуры у меня реализуются одинаково.

Figure.h - базовый класс, от которого наследуются фигуры
Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#pragma once
#include "stdafx.h"
#include "Visitor.h"
 
class CFigure
{
public:
    virtual void accept(CVisitor &visit/*, std::ofstream &outputFile*/) = 0;
};
 
 
class CFabricCreator
{
public:
    virtual CFigure* FabricCreateFigure() = 0;
    virtual ~CFabricCreator() {}
    virtual bool DeleteInstace() = 0;
};


Triangle.h - класс треугольника
Кликните здесь для просмотра всего текста

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
#pragma once
#include "Figure.h"
#include "Visitor.h"
 
class CTriangle : public CFigure
{
public:
    CTriangle(Point point1, Point point2, Point point3);
    ~CTriangle();
    //TODO: теперь управление переходит на паттерн посетитель
    void accept(CVisitor &v/*, std::ofstream &outputFile*/);
 
    std::string GetArea() ;
    std::string GetPerimeter();
    void PrintInFileInfo(/*std::ofstream &file*/);
private:
    Point m_point1, m_point2, m_point3;
    std::string Dlina(std::string a1, std::string b1, std::string a2, std::string b2);
};
 
 
 
class TriangleCreator : public CFabricCreator
{
public:
    static TriangleCreator *GetInstance(Point point1, Point point2, Point point3)
    {
        if (!m_instance)
        {
            m_instance = new TriangleCreator(point1, point2, point3);
        }
        return m_instance;
    }
 
    bool DeleteInstace()
    {
        if (m_instance)
        {
            delete m_instance;
            m_instance = 0;
            return true;
        }
        return false;
    }
 
    CFigure *FabricCreateFigure()
    {
        return new CTriangle(m_point1, m_point2, m_point3);
    }
 
    ~TriangleCreator()
    {
    }
 
protected:
    TriangleCreator(Point point1, Point point2, Point point3) :
        m_point1(point1), m_point2(point2), m_point3(point3) {}
 
    TriangleCreator(const TriangleCreator& triangleCreator);
 
    static TriangleCreator *m_instance;
 
private:
    Point m_point1;
    Point m_point2;
    Point m_point3;
};


Visitor.h - класс посетителя
Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#pragma once
#include "Rectangle.h"
#include "Circle.h"
#include "Triangle.h"
 
class CVisitor
{
public:
    virtual void visit(CRectangle&rec/*, std::ofstream &outputFile*/) = 0;
    virtual void visit(CTriangle&triag/*, std::ofstream &outputFile*/) = 0;
    virtual void visit(CCircle&circ/*, std::ofstream &outputFile*/) = 0;
};
 
 
class CPrintVisitor : public CVisitor
{
public:
    void visit(CRectangle &rec/*, std::ofstream &outputFile*/);
    void visit(CTriangle &triag/*, std::ofstream &outputFile*/);
    void visit(CCircle &circ/*, std::ofstream &outputFile*/);
};


Triangle.cpp - реализация класса треугольник
Кликните здесь для просмотра всего текста

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
#include "stdafx.h"
#include "Triangle.h"
 
 
TriangleCreator *TriangleCreator::m_instance = 0;
 
CTriangle::CTriangle(Point point1,Point point2, Point point3)
:
m_point1(point1),
m_point2(point2),
m_point3(point3)
{
}
 
 
CTriangle::~CTriangle()
{
}
 
void CTriangle::accept(CVisitor &v/*, std::ofstream &outputFile*/)
{
    v.visit(*this/*, outputFile*/);
}
 
std::string CTriangle::GetArea()
{
    CLongArithmetic point1Minus3x = (CLongArithmetic(m_point1.x) - CLongArithmetic(m_point3.x));
    CLongArithmetic point2Minus3y = (CLongArithmetic(m_point2.y) - CLongArithmetic(m_point3.y));
    CLongArithmetic point2Minus3x = (CLongArithmetic(m_point2.x) - CLongArithmetic(m_point3.x));
    CLongArithmetic point1Minus3y = (CLongArithmetic(m_point1.y) - CLongArithmetic(m_point3.y));
    CLongArithmetic multiply1With2 = point1Minus3x * point2Minus3y;
    CLongArithmetic multiply3With4 = point2Minus3x * point1Minus3y;
    CLongArithmetic divide = multiply3With4 - multiply1With2;
    CLongArithmetic result = divide / 2;
 
    return result.ToString();
 
//  return ((m_point1.x - m_point3.x) * (m_point2.y - m_point3.y) \
//  - (m_point2.x - m_point3.x) * (m_point1.y - m_point3.y)) / 2;
}
 
std::string CTriangle::GetPerimeter() 
{
    CLongArithmetic AB(Dlina(m_point1.x, m_point1.y, m_point2.x, m_point2.y));
    CLongArithmetic AC(Dlina(m_point1.x, m_point1.y, m_point3.x, m_point3.y));
    CLongArithmetic BC(Dlina(m_point2.x, m_point2.y, m_point3.x, m_point3.y));
    CLongArithmetic result = AB + AC + BC;
    return result.ToString();
}
 
std::string CTriangle::Dlina(std::string a1, std::string b1, std::string a2, std::string b2)
{
    CLongArithmetic local_a1(a1);
    CLongArithmetic local_b1(b1);
    CLongArithmetic local_a2(a2);
    CLongArithmetic local_b2(b2);
    CLongArithmetic a1a2 = (local_a1 - local_a2) * (local_a1 - local_a2);
    CLongArithmetic b1b2 = (local_b1 - local_b2) * (local_b1 - local_b2);
    CLongArithmetic summ = a1a2 + b1b2;
    CLongArithmetic sqrtNumber = summ.bigSqrt();
 
    return sqrtNumber.ToString();
}
 
void CTriangle::PrintInFileInfo(/*std::ofstream &file*/)
{
    ofstream file("output.txt");
    file << "CIRCLE: P = " << GetArea() << "; S = " << GetPerimeter();
    file << std::endl;
}


Visitor.cpp - реализация класса посетитель
Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include "stdafx.h"
#include "Visitor.h"
 
void CPrintVisitor::visit(CRectangle &rec/*, std::ofstream &outputFile*/)
{
    rec.PrintInFileInfo(/*outputFile*/);
}
 
void CPrintVisitor::visit(CTriangle &triag/*,std::ofstream &outputFile*/)
{
    triag.PrintInFileInfo(/*outputFile*/);
}
 
void CPrintVisitor::visit(CCircle &circ/*, std::ofstream &outputFile*/)
{
    circ.PrintInFileInfo(/*outputFile*/);
}


Может кто увидит в чем ошибки мои, прошу помочь)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
03.04.2016, 21:40
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Паттерн фабрика + синглтон + посетитель (Visual C++):

Фабрика обьектов и названия классов - Visual C++
Вопрос следующий: как можно получить название класса в виде строки, ну или как вариант превратить параметр шаблона(которым и будет этот...

Паттерн Service Layer на с++ - Visual C++
Помогите реализовать паттерн Service Layer на с++ - я уже где только не искал- но на с++ не нашел его реализации

Какой паттерн подойдет, чтобы избежать длинных ветвлений? - C++
здравствуйте, есть код схематично такой: class CTest_base { public: CTest_base() : vec() {} virtual ~CTest_base() noexcept...

Объясните пожалуйста паттерн фабрика - C++
Читаю С. Дьюхерста С++ Священные знания. Там объясняется фабричный метод. Вроде понятно обьект генерирует информацию о себе при этом мы...

Паттерн фабрика - найти и исправить ошибки в проекте - C#
Добрый вечер. У меня возник вопрос при проектировании паттерном абстрактная фабрика у меня есть 1. абстрактная фабрика 2....

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

2
Kronos0041
2 / 2 / 0
Регистрация: 18.03.2014
Сообщений: 146
06.04.2016, 20:24  [ТС] #2
Вот еще main

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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
// Figure.cpp: определяет точку входа для консольного приложения.
//
 
#include "stdafx.h"
#include "Figure.h"
#include "Circle.h"
#include "Rectangle.h"
#include "Triangle.h"
#include "Visitor.h"
 
using namespace std;
 
 
 
 
size_t SwitchFunc(string buf, string* protoCommands)
{
    for (size_t i = 0; i < 3; ++i)
    {
        if (buf == protoCommands[i])
        {
            return i;
        }
    }
    return -1;
}
 
string GetNumber(string &line, int &count)
{
    string tempNumber;
    count++;
    if (!isdigit(line[count]))
    {
        while (!isdigit(line[count]) || count > line.length())
        {
            count++;
        }
    }
    while (isdigit(line[count]))
    {
        tempNumber += line[count];
        count++;
    }
    return tempNumber;
}
 
void GetData(string line, vector<Point> &points)
{
    int count = 0;
    int index = 0;
    string tempNumber;
    while (/*line[count] != '\n' || */count < line.length())
    {
        if (line[count] == 'P')
        {
            count += 2;
        }
        if (line[count] == '=')
        {
            tempNumber = GetNumber(line, count);
            points[index].x = tempNumber.c_str();
        }
        if (line[count] == ',')
        {
            tempNumber = GetNumber(line, count);
            points[index].y = tempNumber.c_str();
            index++;
        }
        count++;
    }
 
}
 
 
void ApplyCommands(ifstream &file, ofstream &outputFile, CFabricCreator *figure)
{
    string line;
 
    vector<CFigure*> figures;
    //TODO: паттерн посетитель
    CPrintVisitor printVisitor;
 
    while (getline(file, line, '\n'))
    {
        string commands[3]
        {
            "TRIANGLE:",
            "RECTANGLE:",
            "CIRCLE:",
        };
        stringstream stringStream;
        stringStream << line;
 
        string commandInLine;
 
        stringStream >> commandInLine;
        if (line.find('\n') == std::string::npos)
        {
            try
            {
            switch (SwitchFunc(commandInLine, commands))
            {
            case 0:
            {
                //TRIANGLE
                if (stringStream >> commands[0])
                {
                    Point triagPoint1 = Point();
                    Point triagPoint2 = Point();
                    Point triagPoint3 = Point();
                    vector<Point> points = { triagPoint1, triagPoint2, triagPoint3 };
                    GetData(line, points);
                    figure = TriangleCreator::GetInstance(points[0], points[1], points[2]);
                    figures.push_back(figure->FabricCreateFigure());
                    figure->DeleteInstace();
                    points.clear();
                    break;
                }
            }
            case 1:
            {
                //RECTANGLE
                if (stringStream >> commands[1])
                {
                    Point recPoint1 = Point();
                    Point recPoint2 = Point();
                    vector<Point> points = { recPoint1, recPoint2 };
                    GetData(line, points);
                    figure = RectangleCreator::GetInstance(points[0], points[1]);
                    figures.push_back(figure->FabricCreateFigure());
                    figure->DeleteInstace();
                    points.clear();
                    break;
                }
            }
            case 2:
            {
                //Circle
                if (stringStream >> commands[2])
                {
                    Point cirCernter = Point();
                    Point cirRadius = Point();
                    vector<Point> points = { cirCernter, cirRadius };
                    GetData(line, points);
                    figure = CircleCreator::GetInstance(points[0], points[1].x);
                    figures.push_back(figure->FabricCreateFigure());
                    figure->DeleteInstace();
                    points.clear();
                    break;
                }
 
            }
            default:
                outputFile << "Неправильная команда" << endl;
 
            }
            }
            catch ( std::exception &ex)
            {
                cout << ex.what() << endl;
            }
        }
    }
    for (int i = 0; i < figures.size(); i++)
    {
        figures[i]->accept(printVisitor);
        //figures[i]->PrintInFileInfo(outputFile);
        //PrintInFileInfo(figures[i].accept(areaOperation), figures[i].accept(perimetrOperation));
    }
}
 
 
int _tmain(int argc, _TCHAR* argv[])
{
     int PARAMS_COUNT = 2;
//  if (argc != PARAMS_COUNT)
//  {
//      cout << "Error of number arguments!" << endl;
//      return 0;
//  }
    CFabricCreator *figure = nullptr;
//  ifstream inputFile(argv[1]);
//  ofstream outputFile(argv[2]);
    ifstream inputFile("input.txt");
    ofstream outputFile("output.txt");
    if (!(inputFile.is_open()))
    {
        cout << "Error of read file" << endl;
        return 0;
    }
    if (!(outputFile.is_open()))
    {
        cout << "Error of write output file" << endl;
        return 0;
    }
    ApplyCommands(inputFile, outputFile, figure);
    outputFile.close();
    inputFile.close();
    if (figure != nullptr)
        delete figure;
    getchar();
    return 0;
}
0
Kronos0041
2 / 2 / 0
Регистрация: 18.03.2014
Сообщений: 146
17.05.2016, 20:46  [ТС] #3
вопрос решен
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.05.2016, 20:46
Привет! Вот еще темы с ответами:

Верно ли, что для добавления нового TabItem отлично подходит паттерн Фабрика объектов - C# WPF
Есть форма с TabControl , по двойному клику создается TabItem со своими Кнопками текстбоксами... Вопрос на понимание - Я правильно понял...

.NET 4.x Паттерн "Абстрактная фабрика" - C#
Есть абстрактный класс Factory: public abstract class Factory { protected string _login; protected string...

Синглтон вызывает синглтон - Java SE
Привет. Что-то запутался. Есть Синглтон(надеюсь я его правильно сделал): public class Table extends JTable { private static...

Синглтон - C++
необходимо разработать класс, который бы гарантировал, что его экземпляр будет один и только один из объектов данного класса


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

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

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