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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.89
revaldo666
9 / 9 / 1
Регистрация: 18.07.2010
Сообщений: 180
#1

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

21.01.2012, 15:05. Просмотров 1173. Ответов 22
Метки нет (Все метки)

Всем доброго времени суток, возник такой вопрос не знаю как реализовать,
имеется 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++):

STL и полиморфизм - C++
Доброго времени суток! Исходная информация: класс а-базовый,b-производный у этих ребят определён виртуальный метод(для класса "a"...

Полиморфизм - C++
Я хотел реализовать множество, используя множественное наследование, но когда написал template <class T> class set { protected: ...

Полиморфизм - C++
Хай :senor: class MyPrint//производный класс { public: MyPrint() { cout << "Constructor MyPrint" << endl; } virtual...

Полиморфизм - C++
В одной дешевой книжке про него пишут а в другой дорогой нет и понять я почему то немогу точно как и для чего он нужен

Полиморфизм - C++
Всем доброго времени суток.Сразу к делу. Если описывать с помощью полиморфизма подклассы и потом динамично их создавать ,то можно вызывать...

Полиморфизм - C++
не могу разобраться с полиморфизмом((( Вот как мне вычислить трапеции. У нее ведь три параметра, а не два как у прямоугольника???? ...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Евгений М.
1035 / 976 / 54
Регистрация: 28.02.2010
Сообщений: 2,829
Завершенные тесты: 2
21.01.2012, 15:24 #2
По очередям есть доки: http://www.cplusplus.com/reference/stl/queue/

Цитата Сообщение от revaldo666 Посмотреть сообщение
Как это реализовать с помощью очереди
Теперь вопрос. Почему не просто односвязный список с возможностью доступа к каждому элементу списка?
revaldo666
9 / 9 / 1
Регистрация: 18.07.2010
Сообщений: 180
21.01.2012, 15:37  [ТС] #3
Ну насчёт очереди я просто предположил.
А насчёт списка, как реализовать сначала просто вызов методов update и draw а если у какого то элемента alive =false то удалять?
Евгений М.
1035 / 976 / 54
Регистрация: 28.02.2010
Сообщений: 2,829
Завершенные тесты: 2
21.01.2012, 16:26 #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
быдлокодер
1694 / 881 / 44
Регистрация: 04.06.2008
Сообщений: 5,441
21.01.2012, 16:32 #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  [ТС] #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
1483 / 1059 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
21.01.2012, 16:40 #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  [ТС] #8
Как заполнить enemyList объектами enemy?
пробовал enemyList.push_back(enemy); -не получилось
DU
1483 / 1059 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
21.01.2012, 17:51 #9
а что не получилось то? копилятор ругаетется? как ругается?
вроде правильно заполняете. весь код выкладывайте
revaldo666
9 / 9 / 1
Регистрация: 18.07.2010
Сообщений: 180
21.01.2012, 17:54  [ТС] #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
1483 / 1059 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
21.01.2012, 18:02 #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  [ТС] #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
1483 / 1059 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
21.01.2012, 18:24 #13
Ну я не знаю что там не просиходит и что должно происходить.
Потратье время на изучение дебагера. В дебаге можно же по шагам прогнать программу, посмотреть значения переменных и много чего еще полезного. Дебагер - вещь простая. Он сэкономит вам кучу времени в будущем.
Евгений М.
1035 / 976 / 54
Регистрация: 28.02.2010
Сообщений: 2,829
Завершенные тесты: 2
21.01.2012, 18:27 #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  [ТС] #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
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.01.2012, 18:33
Привет! Вот еще темы с ответами:

Полиморфизм - C++
Прочитал в Википедии что такое полиморфизм: Кратко смысл полиморфизма можно выразить фразой: «Один интерфейс, множество реализаций». ...

полиморфизм=( - C++
Ув.Знатаки Доброго времени суток!Вот есть проблемка с написание полиморфизма,вот написал класс,написал наследование,а вот как теперь сюда...

Полиморфизм - C++
Всем доброго времени суток, Разъясните пожалуйста задание: Создать класс живущих с местоположением . Определить наследуемые классы -...

Полиморфизм. - C++
Доброго времени суток. Помогите решить следующую задачку: Создать класс периодическое издание (название, стоимость экземпляра и...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
21.01.2012, 18:33
Ответ Создать тему
Опции темы

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