Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Перекрёстная передача указателя на класс методу. методу другого класса. 
V
    Опции темы
Alexk553
Дата 11.11.2009, 23:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 43
Регистрация: 8.11.2009

Репутация: нет
Всего: нет



Совсем недавно стал серьёзно изучать ООП, до этого очень долго работал с чистым С. Вот не могу решить для себя простейшую задачу по применению ООП. Итак,

Простейшая игра:
есть Кот и Собака. У каждого есть два параметра, их характеризующие: количество "жизни" (целая величина, равно 100 и 120, к примеру. Если "жизнь" падает до нуля и ниже, то конец игры). И величина повреждений при ударе(15 и 20). При ударе из жизни вычитается сила удара. Смоделировать пошаговую драку Кота и Собаки. Но от каждого удара они устают, поэтому с каждым новым ударом сила повреждений уменьшается на единицу для кота и на три - для собаки. 
Задачу придумал я себе сам, это не домашнее задание\Кр, как по мне идеально подходит для реализации ООП методом. (и хочу применить наследование (чтобы потом можно было добавить уникальные черты, присущие каждому классу игрока))

Итак, что я делаю. 

Декомпозиция задачи: есть  базовый класс: игрок. От него наследуются два класса: кот и собака. У Игрока есть два параметра: жизнь и сила удара. У Собаки и Кота есть методы (удар). Интерфейс программы: формочка, на ней две кнопки слева и справа ("поцарапать собаку" и "укусить кота"), сверху две пары окошек для вывода чисел: жизнь и сила удара. нажимая на кнопки числа должны меняться согласно условию.

Я пишу:

Код

//gamer.h - файл заголовка , описания классов
class Gamer
{
  public:
       int HitPoints;
       int Damage;
};

class Kot : public Gamer
{public:
    Kot();
   ~Kot();
    void UdaritLapoj(Sobaka *GamerSobaka);
};

class Sobaka : public Gamer
{public:
   Sobaka();
   ~Sobaka();
    void Ukusit(Kot *GamerKot);
};



Код

//gamer.cpp - реализация классов

Kot::Kot()
{
   HitPoints=100;
   Damage=15;
}

Sobaka::Sobaka()
{
   HitPoints=120;
   Damage=20;
}

Kot::UdaritLapoj(Sobaka *GamerSobaka)
{
 GamerSobaka->HitPoints-=this->Damage; // из жизни собаки вычитается сила удара кота
 this->Damage-=1;                                       // и сила удара кота уменьшается на 1 
}

Sobaka::Ukusit(Kot *GamerKot)
{
 GamerKot->HitPoints-=this->Damage; // из жизни кота вычитается сила укуса собаки
 this->Damage-=3;                                       // и укуса собаки уменьшается на 3 
}



собственно уже здесь на этапе компиляции в Microsoft Visual Studio 2008 получается сообщение о том, что 
Error    1    error C2061: syntax error : identifier 'Sobaka'    e:\.......    

вот такая проблема. Насколько я могу понять, на этапе компиляции передача указателя  ещё не определённого класса невозможна. Но загвоздка в симметрии, поменять местами код ничего не даст.  Я понимаю, что эту задачу можно решить кучей методов, вплоть до глобальных переменных, но мой интерс - в наиболее идеологически правильном и красивом ООП решении. Наследование в данном случае чисто для галочки. Читал в Книге про раннее и позднее связывание, что-то похожее описывалось, но в метод не передавался указатель на объект.  

Или же выбрана неправильная модель ?  ведь "атака" влияет на оба объекта. В чём загвоздка?

PM MAIL   Вверх
bsa
Дата 12.11.2009, 00:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



В корне неправильно. Метод удара должен быть у класса Gamer. Конструктор класса Gamer должен принимать два параметра - сила удара и количество жизней.
PM   Вверх
Kipter
Дата 12.11.2009, 05:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 114
Регистрация: 2.5.2006

Репутация: нет
Всего: нет



Про ошибку компилятора:
13: void UdaritLapoj(Sobaka *GamerSobaka); // вы указали что функция принимает в качестве аргумента указатель на объект класса Sobaka, но компилятор ничего еще не знает об этом классе!
16: class Sobaka : public Gamer // ведь класс объявлен ниже!!!

Решение:
class Sobaka; // делаем опережающее объявление

class Kot : public Gamer
{
.... дальше ваш код ...
class Sobaka : public Gamer
{
.... дальше ваш код ...

Тут проблема не только в реализации но и в самой задачи, автор хотел придумать задачу в которой нужно наследование но он ошибся, тут наследование не нужно =)
Собака и Кошка это уже конечные сущности игроков =) Поэтому они скорее объекты чем классы =)

Класс Gamer должен содержать 
- 3 свойства (Кол-во жизней, Сила Удара, Модификатор усталости при ударе) причем c модификатором доступа protected
- Конструктор, в котором задаются эти характеристики
- и 1 Функцию Attack которая принимает ссылку на Gamer 

а потом
Gamer Cat(100, 15, 1);
Gamer Dog(120, 20, 3);
Cat.Attack(Dog);
Dog.Attack(Cat);

Так что вам лучше придумать другую задачу.
Она должна быть куда по сложнее... В классе потомке должны быть более веские отличия от класса предка (например несколько видов атаки) или другая механика атаки.
Т.е например Кошка обладает тремя способностями: Царапнуть, Полоснуть, накинуться и каждая способность имеет свой урон и модификатор усталости
ну и собаке тоже подобные несколько способностей, тогда будет смысл наследовать от базового класса общие детали, а в классе потомке уже определить новые методы.

Еще есть такой момент, писать код желательно так чтобы был понятен смысл действий того или иного его участка.
В данном случае наследование Кота и собаки от Игрока может другого программиста обескуражить, может стоит подобрать другое имя для родительского класса? обозначающее: Животное. существо или еще что, или к коту и собаки приставку сделать чтобы было понятно что это игроки. Но это на ваше усмотрение.

HitPoints ?? 
Очки попаданий?

может имели ввиду
HealthPoints
PM MAIL   Вверх
Alexk553
Дата 12.11.2009, 19:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 43
Регистрация: 8.11.2009

Репутация: нет
Всего: нет



Все спасибо, помогло предварительное объявление. Пока не смог запустить программу, так как другая проблема возникла, но скомпилировалось и слинковалось. Реальная прогшрамма сложнее, чем та, что я привёл, я просто привёл фрагмент кода в минимальном виде, где получился затор. Когда всё заработает, я тут выложу текст,  может, этот пример кому-нибудь поможет... на усмотрение модератора.

Всё, работает как надо, Всем спасибо!

Это сообщение отредактировал(а) Alexk553 - 13.11.2009, 01:36
PM MAIL   Вверх
bsa
Дата 13.11.2009, 11:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196




M
bsa
Alexk553, если ответ на вопрос получен, то пометь тему решенной


PM   Вверх
Alexk553
Дата 13.11.2009, 18:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 43
Регистрация: 8.11.2009

Репутация: нет
Всего: нет



В коде сверху ошибки есть. В конструкторе по умолчанию должны быть операторные скобки: 

{};

тему пометил как решённую.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

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


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0540 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.