Форум программистов, компьютерный форум CyberForum.ru

stl и полиморфизм - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.89
revaldo666
9 / 9 / 1
Регистрация: 18.07.2010
Сообщений: 180
21.01.2012, 15:05     stl и полиморфизм #1
Всем доброго времени суток, возник такой вопрос не знаю как реализовать,
имеется 4 класса.
Базовый Object он имеет поля x и y от него наследуется класс Enemy он имеет метод Draw -прорисовка, от этого класса наследуется ещё 2 класса Bomber и destroyer они имеют методы Update которые обновляют координаты объекта а также имеют булеву переменную alive которая проверяет жив ли объект,
в main я использую такой код
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
CDestroyer destr[3];
    destr[0].Init(300,200,0,0,32,32,"images\\Enemies\\destrojer.bmp",1,2);
    destr[1].Init(370,200,0,0,32,32,"images\\Enemies\\destrojer.bmp",1,2);
    CBomber bomber;
    bomber.Init(400,300,0,0,32,32,"images\\Enemies\\bomber.bmp",1,2);
    CEnemy **enemy;
    enemy=new CEnemy*[3];
    enemy[0]=&destr[0];
    enemy[1]=&destr[1];
    enemy[2]=&bomber;
while(true)
{
               enemy[0]->Update(player.lightlaser.GetX(),player.lightlaser.GetY());
           enemy[1]->Update(player.lightlaser.GetX(),player.lightlaser.GetY());
           enemy[2]->Update(player.lightlaser.GetX(),player.lightlaser.GetY());
                enemy[0]->Draw(buffer);
        enemy[1]->Draw(buffer);
        enemy[2]->Draw(buffer);
 
}
Как это реализовать с помощью очереди(думаю она здесь подойдёт как нельзя лучше)
а также если у объекта alive=false, то чтоб этот объект удалился.
STL юзал буквально несколько раз, поэтому незнаю как это можно провернуть.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.01.2012, 15:05     stl и полиморфизм
Посмотрите здесь:

Полиморфизм C++
Полиморфизм :( C++
C++ Полиморфизм
Полиморфизм c++ C++
C++ Полиморфизм
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Евгений М.
1033 / 974 / 53
Регистрация: 28.02.2010
Сообщений: 2,817
Завершенные тесты: 2
21.01.2012, 15:24     stl и полиморфизм #2
По очередям есть доки: http://www.cplusplus.com/reference/stl/queue/

Цитата Сообщение от revaldo666 Посмотреть сообщение
Как это реализовать с помощью очереди
Теперь вопрос. Почему не просто односвязный список с возможностью доступа к каждому элементу списка?
revaldo666
9 / 9 / 1
Регистрация: 18.07.2010
Сообщений: 180
21.01.2012, 15:37  [ТС]     stl и полиморфизм #3
Ну насчёт очереди я просто предположил.
А насчёт списка, как реализовать сначала просто вызов методов update и draw а если у какого то элемента alive =false то удалять?
Евгений М.
1033 / 974 / 53
Регистрация: 28.02.2010
Сообщений: 2,817
Завершенные тесты: 2
21.01.2012, 16:26     stl и полиморфизм #4
Что-то вроде такого. На компиляторе код не проверял.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <vector>
 
using std::vector;
 
int main()
{
    vector<CEnemy> enemyList;
    vector<CEnemy>::iterator it;
    
    // ...
    for (it=enemyList.begin(); it!=enemyList.end(); it++)
    {
        if (*it.alive == false)
        {
            enemyList.erase(it);
            continue;
        }
        
        *it.Update(...);
        *it.Draw(...);
    }
}
kravam
быдлокодер
 Аватар для kravam
1513 / 873 / 44
Регистрация: 04.06.2008
Сообщений: 5,265
21.01.2012, 16:32     stl и полиморфизм #5
Ну я так понял, ты уже реализовал вызовы Update и Draw теперь очередь за удалением, ну так наверное:
C++
1
2
3
if (enemy[0]->alive =false) {
 //улаляем объект *enemy[0]
}
Тут мне немного непонятно, ты хочешь сделать очередь объектов или очередь указателей на объекты?
Если ты хочешь сделать очередь объектов, например std::deque, тогда удалять просто:
http://www.cplusplus.com/reference/stl/deque/erase/

Посто берёшь имя очереди и делаешь так:
ima.erase(итератор);

С указателями на объекты совсе другой коленкор.
++++++++++++++++++++++++++++++++++++++++++++++++++++++
А может ты решишь написать свою очередь? И опять же, очередь чего? Тогда тоже всё по-другому будет
revaldo666
9 / 9 / 1
Регистрация: 18.07.2010
Сообщений: 180
21.01.2012, 16:36  [ТС]     stl и полиморфизм #6
Цитата Сообщение от Евгений М. Посмотреть сообщение
Что-то вроде такого. На компиляторе код не проверял.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <vector>
 
using std::vector;
 
int main()
{
    vector<CEnemy> enemyList;
    vector<CEnemy>::iterator it;
    
    // ...
    for (it=enemyList.begin(); it!=enemyList.end(); it++)
    {
        if (*it.alive == false)
        {
            enemyList.erase(it);
            continue;
        }
        
        *it.Update(...);
        *it.Draw(...);
    }
}
Спасибо, сейчас попробую
Кстати как присвоить уже заполненный врагами
CEnemy **enemy;
enemy=new CEnemy*[3];
enemy[0]=&destr[0];
enemy[1]=&destr[1];
enemy[2]=&bomber;
И присваивать его нужно в enemyList?
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
21.01.2012, 16:40     stl и полиморфизм #7
ну это кривоватый способ удаления. итератор после ерейза становится невалидным.
есть более кошерный с алгоритмами. если есть возможность заюзать лябды нового стандарта или бинды из буста или тр1, то все это можно организовать без ф-ии IsDead

C++
1
2
3
4
5
6
7
8
9
10
11
12
bool IsDead(const CEnimy& enimy)
{
  return !enimy.alive;
}
 
// вот после этого в листе не останется ни одного объката, для которого ф-ия IsDead
// вернет true.
enimyList.erase(std::remove_if(enimyList.begin(), enimyList.end(), &IsDead), enimyList.end());
 
// ну и дальше уже манипулировать только живыми объектами. Мешать в одном цикле
// удаление и вызовы прочих методов как-то не хорошо, даже несмотря на то,
// что в этом случае экономится один проход по контейнеру.
Еще иерархия какая-то кривая. Почему бы в базовый класс не поместить методы Draw и Update. Ведь они имеют смысл для всех объектов.
revaldo666
9 / 9 / 1
Регистрация: 18.07.2010
Сообщений: 180
21.01.2012, 17:17  [ТС]     stl и полиморфизм #8
Как заполнить enemyList объектами enemy?
пробовал enemyList.push_back(enemy); -не получилось
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
21.01.2012, 17:51     stl и полиморфизм #9
а что не получилось то? копилятор ругаетется? как ругается?
вроде правильно заполняете. весь код выкладывайте
revaldo666
9 / 9 / 1
Регистрация: 18.07.2010
Сообщений: 180
21.01.2012, 17:54  [ТС]     stl и полиморфизм #10
Цитата Сообщение от DU Посмотреть сообщение
а что не получилось то? копилятор ругаетется? как ругается?
вроде правильно заполняете. весь код выкладывайте
Сделал так
C++
1
2
3
vector <CEnemy**> lst;
    lst.push_back(enemy);
    vector<CEnemy**>::iterator it;
вроде всё получилось, однако
когда запускаю цикл
C++
1
2
3
4
5
6
7
for(it=lst.begin();it!=lst.end();it++)
            {
                if(*it.alive==false) //поля alive не существует
                {
 
                }
            }
то итератор не имеет никаких полей класса CEnemy
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
21.01.2012, 18:02     stl и полиморфизм #11
ну у вас вектор содержит указатель на указатель на CEnemy;
Вам в вектор нужно складывать либо указатели на CEnemy либо даже значения

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Вариант с указателями:
std::vector<CEnemy*> enemiesList;
enemiesList.push_back(new CEnemy());
std::vector<CEnemy*>::const_iterator iter = enemiesList.begin();
const bool isAlive = (*iter)->alive;
// тип результата выражения (*iter) - указатель на CEnemy.
// поэтому обращение к объекту как к указателю, через стрелочку.
 
В случае, когда в векторе будут указатели, нужно будет не забывать вызывать для этих указателей delete, когда эти указатели будут удалятся из вектора. Сам вектор delete для этих указателей не позовет.
 
// Вариант с значениями:
std::vector<CEnemy> enemiesList;
enemiesList.push_back(CEnemy());
std::vector<CEnemy>::const_iterator iter = enemiesList.begin();
const bool isAlive = (*iter).alive;
// тип результата выражения (*iter) - ссылка на CEnemy.
// поэтому обращение к объекту по ссылке, т.е. через точку.
В случае с указателями при удалении указателя из вектора нужно будет не забыть для этого указателя позвать delete. Сам вектор не будет звать для них delete. Он просто удалит их из себя и все.
revaldo666
9 / 9 / 1
Регистрация: 18.07.2010
Сообщений: 180
21.01.2012, 18:14  [ТС]     stl и полиморфизм #12
Это понятно, однако когда вызываю в цикле метод Update, ничего не происходит
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
CDestroyer destr[3];
    destr[0].Init(300,200,0,0,32,32,"images\\Enemies\\destrojer.bmp",1,2);
    destr[1].Init(370,200,0,0,32,32,"images\\Enemies\\destrojer.bmp",1,2);
    destr[2].Init(400,300,0,0,32,32,"images\\Enemies\\destrojer.bmp",1,2);
    CBomber bomber;
    bomber.Init(400,300,0,0,32,32,"images\\Enemies\\bomber.bmp",1,2);
    CEnemy **enemy;
    enemy=new CEnemy*[3];
    enemy[0]=&destr[0];
    enemy[1]=&destr[1];
    enemy[2]=&bomber;
    std::vector<CEnemy*> enemiesList;
enemiesList.push_back(new CEnemy());
std::vector<CEnemy*>::const_iterator iter = enemiesList.begin();
const bool isAlive = (*iter)->alive;
    bool done=false;
    CPlayer player;
    int g=700,j=0;
    player.Init(400,400,0,Down,32,32,"images\\mainShip\\mths.bmp",1,2);
    while(!done)
    {
        while(counter>0)
        {
            if(key[KEY_ESC])
                done=true;
            player.Update();
            for(iter=enemiesList.begin();iter!=enemiesList.end();iter++)
            {
                (*iter)->Update(player.lightlaser.GetX(),player.lightlaser.GetY());
            }
            counter--;  
        }
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
21.01.2012, 18:24     stl и полиморфизм #13
Ну я не знаю что там не просиходит и что должно происходить.
Потратье время на изучение дебагера. В дебаге можно же по шагам прогнать программу, посмотреть значения переменных и много чего еще полезного. Дебагер - вещь простая. Он сэкономит вам кучу времени в будущем.
Евгений М.
1033 / 974 / 53
Регистрация: 28.02.2010
Сообщений: 2,817
Завершенные тесты: 2
21.01.2012, 18:27     stl и полиморфизм #14
Цитата Сообщение от revaldo666 Посмотреть сообщение
в цикле метод Update, ничего не происходит
А мы не знаем что должно происходить. Draw не забыли?

Кстати, можно как-то без итераторов обойтись:
C++
1
2
3
4
5
for (size_t i=0; i<enemyList.size(); i++)
{
  enemyList[i].Update();
  enemyList[i].Draw();
}
revaldo666
9 / 9 / 1
Регистрация: 18.07.2010
Сообщений: 180
21.01.2012, 18:33  [ТС]     stl и полиморфизм #15
В enemyList просто не присваиваются данные которыми инициализирован enemy
Сделал так
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
std::vector <shared_ptr<CEnemy>> lst; 
     lst.insert(lst.end(),enemy,enemy+3);
     std::vector <shared_ptr<CEnemy>>:: iterator iter;
     iter=lst.begin();
while(true)
{
for(iter=lst.begin();iter!=lst.end();iter++)
    {
        if((*iter)->alive==false)
        lst.erase(iter);
        (*iter)->Update(player.lightlaser.GetX(),player.lightlaser.GetY());
    }
for(iter=lst.begin();iter!=lst.end();iter++)
    {
        
        (*iter)->Draw(buffer);
    }
 
}
Работает, однако когда alive становится false выскакивает debug error, а если без этого условия, то при закрытии приложения тот же самый debug error
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
21.01.2012, 18:37     stl и полиморфизм #16
ну я вроде написал что после ерейза итератор становится невалидным. обращатся к нему уже нельзя. а у вас в коде идет удаление, а потом обращение к этому итератору. удалите сперва из контейнера все мертвые обхъекты, а потом уже в цикле апдейт зовите. если же хотите в одном цикле удалять и апдейтить, то придется подправлять итераторы после удаления чего-либо из контейнера

апдейт поместите рядом с дроу, в цикл, где идет перебор живых врагов.
revaldo666
9 / 9 / 1
Регистрация: 18.07.2010
Сообщений: 180
21.01.2012, 18:40  [ТС]     stl и полиморфизм #17
Та даже если я ничего не удаляю(удаление полностью комментировал) всё равно debug error выкидывает когда приложение закрывается.
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
21.01.2012, 18:44     stl и полиморфизм #18
ну тогда весь код проще сюда выложить.
revaldo666
9 / 9 / 1
Регистрация: 18.07.2010
Сообщений: 180
21.01.2012, 18:45  [ТС]     stl и полиморфизм #19
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
volatile long counter=0;
void increment()
{
    counter++;
}
#include"allegro\include\allegro.h"
#include"defines.h"
#include"Player.h"
#include"Destroyer.h"
#include "Bomber.h"
#include<vector>
using std::vector;
bool IsDead(const CEnemy& enemy)
{
  return !enemy.alive;
}
int main(void)
{
    allegro_init();
    install_keyboard();
    install_sound(DIGI_AUTODETECT,MIDI_AUTODETECT,"A");
    MIDI * fon;
    fon=load_midi("sounds\\1 (8).mid");
    play_midi(fon,true);
    set_color_depth(32);
    set_gfx_mode(GFX_AUTODETECT_WINDOWED,WinWidth,WinHeight,0,0);
    set_window_title("Space Invaders");
    LOCK_VARIABLE(counter);
    LOCK_FUNCTION(increment);
    install_int_ex(increment,BPS_TO_TIMER(100));
    BITMAP * buffer=create_bitmap(WinWidth,WinHeight);
    BITMAP* bg=load_bitmap("images\\background\\Level_6.bmp",NULL);
    CDestroyer destr[3];
    destr[0].Init(300,200,0,0,32,32,"images\\Enemies\\destrojer.bmp",1,2);
    destr[1].Init(370,200,0,0,32,32,"images\\Enemies\\destrojer.bmp",1,2);
    destr[2].Init(400,300,0,0,32,32,"images\\Enemies\\destrojer.bmp",1,2);
    CBomber bomber;
    bomber.Init(400,300,0,0,32,32,"images\\Enemies\\bomber.bmp",1,2);
    CEnemy **enemy;
    enemy=new CEnemy*[3];
    enemy[0]=&destr[0];
    enemy[1]=&destr[1];
    enemy[2]=&bomber;
     std::vector <shared_ptr<CEnemy>> lst; 
     lst.insert(lst.end(),enemy,enemy+3);
     std::vector <shared_ptr<CEnemy>>:: iterator iter;
     iter=lst.begin();
     
 
    bool done=false;
    CPlayer player;
    int g=700,j=0;
    player.Init(400,400,0,Down,32,32,"images\\mainShip\\mths.bmp",1,2);
    while(!done)
    {
        while(counter>0)
        {
            if(key[KEY_ESC])
                done=true;
            player.Update();
            for(iter=lst.begin();iter!=lst.end();iter++)
            {
                if((*iter)->alive==false)
                    lst.erase(iter);
                (*iter)->Update(player.lightlaser.GetX(),player.lightlaser.GetY());
            }
            counter--;  
        }
        j++;
        if(g>=-350&&j%4==0)
        {
            g--;
        }
        if(g==-350)
        {
            g=900;
            
        }
        blit(bg,buffer,0,g,0,0,WinWidth,WinHeight);
        player.Draw(buffer);
        for(iter=lst.begin();iter!=lst.end();iter++)
            {
                (*iter)->Draw(buffer);
            }
        blit(buffer,screen,0,0,0,0,WinWidth,WinHeight);
        clear_bitmap(buffer);
    }
    return 0;
}
END_OF_MAIN()
Надеюсь классы вылаживать не нужно))
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.01.2012, 18:50     stl и полиморфизм
Еще ссылки по теме:

Полиморфизм C++
C++ STL и полиморфизм
C++ Полиморфизм

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

Или воспользуйтесь поиском по форуму:
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
21.01.2012, 18:50     stl и полиморфизм #20
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
        CDestroyer destr[3];
        destr[0].Init(300,200,0,0,32,32,"images\\Enemies\\destrojer.bmp",1,2);
        destr[1].Init(370,200,0,0,32,32,"images\\Enemies\\destrojer.bmp",1,2);
        destr[2].Init(400,300,0,0,32,32,"images\\Enemies\\destrojer.bmp",1,2);
        CBomber bomber;
        bomber.Init(400,300,0,0,32,32,"images\\Enemies\\bomber.bmp",1,2);
        CEnemy **enemy;
        enemy=new CEnemy*[3];
        enemy[0]=&destr[0];
        enemy[1]=&destr[1];
        enemy[2]=&bomber;
         std::vector <shared_ptr<CEnemy>> lst; 
         lst.insert(lst.end(),enemy,enemy+3);
В вектор вы складываете шаред поинтеры, которые инициализируются указателями на объекты, которые у вас на стеке.
Когда вызывается деструктор вектора, он удаляет все свое содержимое, все шаред поинтеры. Каждый шаред поинтер, когда удаляется, вызывает делете для того указателя, на который он указывает. Далее у вас удаляются те же самые объекты, которые на стеке. Итого получаем двойное удаление одних и тех же объектов.
Yandex
Объявления
21.01.2012, 18:50     stl и полиморфизм
Ответ Создать тему
Опции темы

Текущее время: 08:16. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru