Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.71/7: Рейтинг темы: голосов - 7, средняя оценка - 4.71
95 / 4 / 0
Регистрация: 04.12.2015
Сообщений: 19

Найти причины ошибок времени компиляции внутри класса, генерируемого фабричной функцией

29.08.2016, 17:48. Показов 1706. Ответов 35
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Друзья! Начиталась я книжек о паттернах и решила попробовать в деле. Все работало, пока я не добавила "улучшений" в виде умных указателей, которые тоже только начала изучать. И теперь компилятор нещадно ругается на меня последними словами. Экземпляры классов создаются фабричными функциями, возвращающими shared_ptr:
C++
1
return shared_ptr<Object>(new Constant(1, name));
кроме того, есть составные объекты, которые содержат вектор экземпляров родственных классов (компоновщик).
C++
1
2
3
vector<shared_ptr<Object>>object;
....
shared_ptr<Object> mEx = creator.createObject(8, object);
Вот что происходит в фабрике для составных объектов:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
shared_ptr<Object> Creator::createObject(int id, vector<shared_ptr<Object>>str)
{
    if (id == 8)
    {
        shared_ptr<Object> obj = std::make_shared<MathExp>(1, str);
        return obj;
    }
    else if (id == 9)
    {
        shared_ptr<Object> obj = std::make_shared<JumpIf>(1, str);
        return obj;
    }
}
И вот как раз в конструкторе этого класса происходит страшная ругань.
Вот так было:
C++
1
2
MathExp::MathExp(int c, vector<Object*>str)
    : Object(c), objects(str){}
вот так стало:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class MathExp : public Object
{
public:
    MathExp(int, vector<shared_ptr<Object>>);
    
    virtual void accept(Visitor&);
 
private:
    vector<shared_ptr<Object>>objects;
    
};
 
MathExp::MathExp(int c, vector<shared_ptr<Object>>str)
    : Object(c), objects(str){}
Пишет, что экземпляр перегруженной функции не соответствует заданному типу.
Думала, проблема циклических зависимостей, попробовала переписать вектор в классе MathExp как вектор weak_ptr, но не помогло. Пробовала копировать в вектор пообъектно через for, без изменений.
2
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
29.08.2016, 17:48
Ответы с готовыми решениями:

Найти причины возникновения ошибок в коде и исправить эти ошибки (динамический массив как поле класса)
когда запускаю, пишет что нет прав доступа для записи в память. если писать без класса, то все работает P.S. использую MVS Express 2015...

Найти причины и способы устранения ошибок в коде
В онлайн компиляторе выдает ошибки: Compiler Output: ZP9NviRq.c:2:16: error: math: No such file or directory ZP9NviRq.c: In function...

Найти причины и способы исправления ошибок в коде
Программа завершается при деление с плохим кодом -0блаблабла, что делать? 2 день программирую слишком тупой чтобы понять эту штуку ...

35
95 / 4 / 0
Регистрация: 04.12.2015
Сообщений: 19
30.08.2016, 14:30  [ТС]
Студворк — интернет-сервис помощи студентам
Ну что сказать. После вчерашних 116 ошибок я просто закрыла студию, а потом открыла. (Как там говорят сисадмины "а вы пробовали выключить, а потом включить?") Ошибок оказалось 37. Я проследила циклические включения #include и исправила 1 ошибку из списка, которую поняла: заменила int на size_t в функции, которая проходит по стрингу, хотя непонятно, почему до внесения умных указателей оно все же компилировалось. Проект скомпилировался без утечек памяти и даже выдал верный результат. Никак чудо. Всем большое спасибо, что откликнулись. На счет замечаний по поводу оформления и стиля, с радостью выслушаю, я ведь собираюсь все-таки показать этот проект, и чтобы за него не было стыдно.
2
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
30.08.2016, 14:58
Цитата Сообщение от Havana Посмотреть сообщение
На счет замечаний по поводу оформления и стиля
Вероятно можно за typedef-ить имена указателей и вектора что бы сократить запись.
Вектор передавать по константной ссылке.

C++
1
if (id == 8)
8- и прочие "магические числа" заменить на константы из enum
1
90 / 88 / 33
Регистрация: 20.07.2016
Сообщений: 403
30.08.2016, 15:14
Цитата Сообщение от Avazart Посмотреть сообщение
Вероятно можно за typedef-ить имена указателей и вектора что бы сократить запись.
Havana, ну либо использовать auto почаще...

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
shared_ptr<Object> Creator::createObject(int id, string name)
{
    switch (id)
    {
    case 1:
        SymbolTable::instance().addSymbol(name);
        return shared_ptr<Object>(new Constant(1, name));
        break;
    case 2:
        SymbolTable::instance().addSymbol(name);
        return shared_ptr<Object>(new Variable(1, name));
        break;
    case 3:
        return shared_ptr<Object>(new Assign(1, name));
        break;
    case 4:
        return shared_ptr<Object>(new MathOp(1, name));
        break;
    case 6:
        return shared_ptr<Object>(new Address(1, name));
        break;
    case 7:
        return shared_ptr<Object>(new LogicOp(1, name));
        break;
    }
}
везде где есть подобный стиль - меняем так чтоб был один оператор return... да вообще такой стиль (через switch) в ООП не особо приветствуется...

Добавлено через 3 минуты
Цитата Сообщение от Havana Посмотреть сообщение
заменила int на size_t в функции, которая проходит по стрингу
если точные значения индексов не нужны лучше пользоваться итераторами и осуществлять проход до .end()... так наверняка ошибок не будет...
1
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
30.08.2016, 16:14
Цитата Сообщение от JIawliet Посмотреть сообщение
ну либо использовать auto почаще...
auto для лентяев.... читать сложно если весь код сплошное auto

Добавлено через 3 минуты
C++
1
2
3
4
 case 1:
        SymbolTable::instance().addSymbol(name);
        return shared_ptr<Object>(new Constant(1, name));
        break;
break - лишний если есть return. Ну и std::make_shared

Добавлено через 2 минуты
Цитата Сообщение от JIawliet Посмотреть сообщение
да вообще такой стиль (через switch) в ООП не особо приветствуется...
Да все нормально, как иначе? Это же параметризированный фабричный метод
1
90 / 88 / 33
Регистрация: 20.07.2016
Сообщений: 403
30.08.2016, 16:45
Цитата Сообщение от Avazart Посмотреть сообщение
Да все нормально, как иначе? Это же параметризированный фабричный метод
да, реализация Factory Method стандартная, все ок...
просто предпочитаю порождение объектов через Prototype (+ хранилище / реестр прототипов)...
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
30.08.2016, 17:57
Ну прототип совсем другая штука. А реестр это через макросы что ли?
0
90 / 88 / 33
Регистрация: 20.07.2016
Сообщений: 403
30.08.2016, 18:46
Цитата Сообщение от Avazart Посмотреть сообщение
Ну прототип совсем другая штука.
Ну почему же, это тоже порождающий паттерн, но реализация порождения объектов другая...
Цитата Сообщение от Avazart Посмотреть сообщение
А реестр это через макросы что ли?
что? нет конечно... это ассоциативный контейнер, хранящий индексы и соответствующие им объекты...

Добавлено через 26 минут
Avazart
вот небольшой пример:
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
#include <iostream>
#include <map>
#include <vector>
 
//=============================================================================
enum ID { frst, scnd };
 
class Parent;
 
typedef std::map<ID, Parent*> Registry;
 
Registry& getRegistry ()
{
    static Registry regInst;
    return regInst;
}
 
//=============================================================================
class Helper {};
 
//=============================================================================
// Parent
class Parent
{
protected:
    void addPrototype (ID id, Parent* ptr)
    {
        auto& reg = getRegistry();
        reg[id] = ptr;
    }
 
public:
    static Parent* createObject (ID id)
    {
        auto& reg = getRegistry();
        if (reg.find(id) != reg.end())
            return reg[id] -> clone();
        return nullptr;
    }
 
    virtual void info () = 0;
    virtual Parent* clone () = 0;
 
    virtual ~Parent () {}
};
 
//=============================================================================
// First
class First: public Parent
{
private:
    First () {}
 
    First (Helper)
    { Parent::addPrototype(frst, this); }
 
    static First prototype;
 
public:
    void info () override
    { std::cout << "First" << std::endl; }
 
    Parent* clone () override
    { return new First(*this); }
};
 
//=============================================================================
// Second
class Second: public Parent
{
private:
    Second () {}
 
    Second (Helper)
    { Parent::addPrototype(scnd, this); }
 
    static Second prototype;
 
public:
    void info () override
    { std::cout << "Second" << std::endl; }
 
    Parent* clone () override
    { return new Second(*this); }
};
 
//=============================================================================
// static
First First::prototype = First(Helper());
Second Second::prototype = Second(Helper());
 
//=============================================================================
int main ()
{
    std::vector<Parent*> vp;
    vp.push_back(Parent::createObject(frst));
    vp.push_back(Parent::createObject(frst));
    vp.push_back(Parent::createObject(scnd));
 
    for (const auto& j : vp)
        j -> info();
 
    for (auto j : vp)
        delete j;
 
    return 0;
}
1
 Аватар для Nosey
1379 / 406 / 144
Регистрация: 22.10.2014
Сообщений: 872
30.08.2016, 20:11
JIawliet, Почему не канонический IPrototype а непонятный Parent?
А также:
C++
1
2
3
4
...
Parent* First::clone () override
    { return new First(*this); }
...
->
C++
1
2
3
4
...
First* First::clone () override
    { return new First(*this); }
...
0
90 / 88 / 33
Регистрация: 20.07.2016
Сообщений: 403
30.08.2016, 20:25
Цитата Сообщение от Nosey Посмотреть сообщение
Почему не канонический IPrototype а непонятный Parent?
Потому что это всего лишь пример, писал его наспех... можно еще придраться допустим к серийным операторам for:
C++
1
2
3
4
5
for (const auto& j : vp)
        j -> info();
 
for (auto j : vp)
       delete j;
в первом нет проверки на nullptr, во втором для явной демонстрации намерений нужно написать auto& (хотя на результат это не влияет)...
но так как я не гуру, мне простительно
1
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
30.08.2016, 23:13
Цитата Сообщение от Havana Посмотреть сообщение
просто всегда кажется
да как бе не важно, что вам кажется.
машина делает не то, о чем подумал человек.
а то, что он сказал ей делать.
именно по этой причине существует эта тема.

вы оказались не в состоянии грамотно сформулировать свой вопрос.
можете наслаждаться мужским вниманием к своей особе.
только толку от этого не будет для решения вашей задачи.

а можете поучиться грамотно оформлять материал,
и формулировать запрос к коллективному разуму.
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
31.08.2016, 00:13
Цитата Сообщение от hoggy Посмотреть сообщение
а можете поучиться грамотно оформлять материал,
и формулировать запрос к коллективному разуму.
Как правило в таких случаях, когда правильно сформулируешь уже помощь не нужна к тому моменту...
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
31.08.2016, 00:31
Цитата Сообщение от Avazart Посмотреть сообщение
Как правило в таких случаях, когда правильно сформулируешь уже помощь не нужна к тому моменту...
часто так и есть.
в этом заключается смысл моего посыла.

ребята говорят: она на правильном пути.
я не хочу показаться грубым, но у меня такая подача материала вызвала раздражение,
из-за неспособности помочь, потому что материал невозможно воспроизвести,
и установить ошибку.

так и хочется сказать: ну ждите тогда телепатов!
или наслаждайтесь мужским вниманием.
0
31.08.2016, 00:35

Не по теме:

Цитата Сообщение от hoggy Посмотреть сообщение
из-за неспособности помочь, потому что материал невозможно воспроизвести,
и установить ошибку.
Ну там походу был вечерний перегруз мозгов, утром же на свежую голову разрулила сама, значит все норм.

0
31.08.2016, 00:41

Не по теме:

Цитата Сообщение от Avazart Посмотреть сообщение
значит все норм.
а ещё раздражают люди, которые поимев решение,
забивают на тему, не показав результата.

получил решение? поделись результатом.
в эту тему по гуглу зайти могут.

0
31.08.2016, 10:12

Не по теме:

Цитата Сообщение от hoggy Посмотреть сообщение
получил решение? поделись результатом.
в эту тему по гуглу зайти могут.
Так описала же в чем проблема была и как решила... Не выкладывать же весь проект.

0
05.09.2016, 13:08  [ТС]

Не по теме:

Avazart, спасибо за адекватность

Добавлено через 2 минуты
hoggy, забыли добавить "иди лучше борщи варить". А внимательность к прочитанным сообщениям не помешала бы даже гениям, способным сходу понять и сформулировать источник проблемы.

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
05.09.2016, 13:08

Найти причины и способы исправления ошибок в коде
Приложил фото ошибки, не считает часовые пояса. Объясните, что не так. # include &lt;iostream.h&gt; # include &lt;conio.h&gt; # include...

Найти причины и способы исправления ошибок в коде
#include &lt;stdio.h&gt; #include &lt;time.h&gt; #include &lt;stdlib.h&gt; int main () { int i,p,j,a; int k; int m; ...

Найти причины и способы исправления ошибок в коде
ввожу: 2 + тут он мне пишет &quot;???&quot; #include &lt;stdio.h&gt; #include &lt;iostream&gt; #include &lt;string&gt; int main(void) { int...

Найти причины и способы исправления ошибок в коде
Помогите найти ошибку, вылетает где то в for. #include &lt;iostream&gt; #include &lt;map&gt; #define gc getchar using namespace std; ...

Найти причины и способы исправления ошибок в коде
почему не работает??? #include &lt;iostream&gt; #include &lt;conio.h&gt; #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; using namespace std; ...


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

Или воспользуйтесь поиском по форуму:
36
Ответ Создать тему
Новые блоги и статьи
Сезонность и суточность закисления почв
anaschu 04.07.2026
200 часов это все равно моловато. Есть ситуации, но нестандартные, когда смена происходит за 5 лет. Но обычно это 50 лет и более. Наверное, закисление почвы происходит сезонно в средней. . .
В чем ценность человеческого опыта в глобальном смысле?
kumehtar 03.07.2026
Возможно, ценность человека не в том, что он однажды достигает мудрости, а в том, что он становится носителем карты пути. Он знает не только истину, но и последовательность внутренних изменений,. . .
интеграция AnyLogic с самописным REST API и переход на Odoo
anaschu 03.07.2026
Успешная интеграция AnyLogic с самописным REST API и переход на промышленную Odoo WMS Сегодня проделал огромный путь от простой симуляции физических процессов до построения полноценной. . .
Поиск всех путей на ориентированном графе. Linux
dcc0 02.07.2026
Переработка старого кода из моей статьи. Через несколько переработок от PHP кода к C89 (надеюсь, 89). Но довольно запутанно получилось. Код для Linux. Но если убрать time и то, что с ним. . .
Сам себя обучал rest api
anaschu 02.07.2026
Педагогический лайфхак: Почему чистый REST API для ученика намного круче, чем готовые библиотеки Когда мы отказались от капризного JAR-файла AnyLogic и переписали код на стандартный HttpClient,. . .
rest api anylogic - выполнение модели на своём русском сайте
anaschu 02.07.2026
Как подружиться с AnyLogic Cloud API, победить провайдеров и развернуться Java-бэкенд в Docker на бесплатном хостинге: Двухдневный лог борьбы Всем привет! Хочу поделиться свежим (и довольно. . .
Где деньги лежат
kumehtar 02.07.2026
Это - японская подводная лодка I-52 (тип C2, кодовое имя Momi) вышла из Японии в марте 1944 года с миссией в оккупированную немцами Францию (Лорьян). Это была одна из «Янаги»-миссий по обмену. . .
Krabik для WoW 3.3.5a, многоязычный
AmbA 02.07.2026
Допилил бота, думаю что окончательно. Изменения: - добавлена многоязычность - добавлено снятие скриншотов - добавлено поддержание бафов хождения по воде (для жреца, дк и шамана) - и так, по. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru