Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.88/34: Рейтинг темы: голосов - 34, средняя оценка - 4.88
54 / 54 / 9
Регистрация: 09.11.2010
Сообщений: 120
1

Взаимодействие объектов разных классов

12.02.2011, 22:39. Показов 6854. Ответов 12
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Я или туплю или чего-то не понимаю\не до понимаю. Вопрос в самом коде.
Код
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
class Player
{
        int health;
    int damage;
public:
    Player() { health = damage = 0; }
 
    void setParam(int h, int d)
    {
        health = h;
        damage = d;
    }
 
    int getHealth() { return health; }
    int getDamage() { return damage; }
};
 
class Enemy
{
    int health;
    int damage;
public:
    Enemy() { health = damage = 0; }
    void setParam(int h, int d)
    {
        health = h;
        damage = d;
    }
 
     int getHealth() { return health; }
     int getDamage() { return damage; }
 
};
 
void Attack(Player &player, Enemy &enemy)
{   
    enemy.getHealth() -= player.getDamage(); // как здесь заставить взаимодействовать объектам двух разных классов?
    player.getHealth() -= enemy.getDamage(); // аналогично        
}
 
int main()
{
    Player player;
    Enemy enemy;
 
    player.setParam(100, 50);
    enemy.setParam(100,30);
    Attack(player, enemy);
 
return 0;
}

Жалуется на то, что "-=" должен быть левосторонним значением. Чем ему функции не угодили?

UPD:
В общем сделал через friend-функции
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Enemy;
 
class Player
{
        int health;
    int damage;
public:
           friend void Attack(Player &player, Enemy &enemy);
};
 
class Enemy
{
        int health;
    int damage;
public:
           friend void Attack(Player &player, Enemy &enemy);
};
 
friend void Attack(Player &player, Enemy &enemy)
{
    enemy.health -= player.damage;
    player.health -= enemy.damage;
}
Допустим ли такой метод взаимодействия? Как вообще делать "правильно"?
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
12.02.2011, 22:39
Ответы с готовыми решениями:

Разработать иерархию классов, демонстрирующее работу с коллекцией объектов разных классов
Задание: Разработать в соответствии с индивидуальным заданием иерархию классов и приложение,...

Массив объектов разных производных классов
Задача такая: базовый класс - фигура, производные классы - круг, треугольник и т.п. Пользователь...

Создание коллекции объектов разных классов
Здравствуйте. Помогите, пожалуйста, с задачкой создания коллекции объектов разных типов. Я сначала...

Вектор объектов разных классов. Полиморфим
В общем проблема такая: есть вектор объектов разных классов, надо вывести информацию о каждом...

12
Эксперт С++
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
12.02.2011, 22:57 2
Мне кажется вот так будет логичнее:
C++
1
2
3
4
5
void Attack(Player &player, Enemy &enemy)
{       
    enemy   .dec_health(player  .getDamage());
    player  .dec_health(enemy   .getDamage());        
}
1
54 / 54 / 9
Регистрация: 09.11.2010
Сообщений: 120
12.02.2011, 23:11  [ТС] 3
Mr.X, эм, сижу пытаюсь понять но ... Не могли бы прокомментировать? Что это за конструкции в качестве параметров?

Не по теме:

Опечатался в первом посте, friend-лишний. Не могу отредактировать =(

0
Эксперт С++
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
13.02.2011, 00:19 4
Цитата Сообщение от Escapable Посмотреть сообщение
Mr.X, эм, сижу пытаюсь понять но ... Не могли бы прокомментировать? Что это за конструкции в качестве параметров?
Я имел в виду, что нужно в классе Enemy объявить интерфейсную функцию
C++
1
2
3
4
int  dec_health(int  damage) 
{
    health -= damage; 
}
в которую передается значение, возвращаемое функцией getDamage() класса Player, и наоборот.
1
54 / 54 / 9
Регистрация: 09.11.2010
Сообщений: 120
13.02.2011, 00:33  [ТС] 5
Mr.X, теперь все понятно. Спасибо.

А как насчет "друзей"? Пытаться избегать или использовать в разумных пределах?
0
║XLR8║
1212 / 909 / 270
Регистрация: 25.07.2009
Сообщений: 4,361
Записей в блоге: 5
13.02.2011, 01:28 6
Escapable, Меня самого заинтересовала тема наследования с этой стороны, в кратце: берем базовый класс для Игрока и Атакованого, и создаем в нем метод который уменьшает жизни, далее смотрим код:
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
#include <iostream>
#include <string>
 
using namespace std;
 
class Actor
{
protected:
        int health;
        int damage;
        string name;
public:
        Actor (string name = "Actor") 
        { 
                health = damage = 0;
                this->name = name;
        }
 
        void setParam(const int &health, const int &damage)
        {
                this->health = health;
                this->damage = damage;
        }
        
        void showStates()
        {
                cout << this->name << "\n\rHealth: " << this->health 
                     << ", damage: " << this->damage << endl;
        }
        
        void Attack(Actor *destination)
        {
                destination->health -= this->damage;
        }
};
 
class Player : public Actor
{
public:
        Player (string name) : Actor(name) { }
};
 
class Enemy : public Actor 
{
public:
        Enemy (string name) : Actor(name) { }
};
 
int main()
{
        Player player("Player");
        Enemy enemy("Enemy");
        player.setParam(100, 50);
        enemy.setParam(100,30);
        
        player.showStates();
        enemy.showStates();
 
        player.Attack(&enemy);
        
        player.showStates();
        enemy.showStates();
        
        system("pause");
        return 0;
}
Добавлено через 6 минут
http://codepad.org/pC0kMZvs
1
54 / 54 / 9
Регистрация: 09.11.2010
Сообщений: 120
13.02.2011, 01:37  [ТС] 7
outoftime, спасибо за еще одну наводку. О наследовании, в данном случае, чего-то не подумал.

Про "друзей" вопрос открыт.
0
Эксперт С++
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
13.02.2011, 07:58 8
А я что-то не обратил внимания, что классы одинаковые. Тогда логичнее так сделать:
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
/////////////////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <string>
/////////////////////////////////////////////////////////////////////////////////////////
class T_actor
{
    typedef std::string  T_name;
    //-----------------------------------------------------------------------------------
    T_name  name_;
    int     health_;
    int     damage_;
public:
    //-----------------------------------------------------------------------------------
    T_actor
        (
            T_name  name,
            int     health = 0, 
            int     damage = 0
        ) 
        : name_    (name),
          health_  (health), 
          damage_  (damage)
    {}
    //-----------------------------------------------------------------------------------
    void attack(T_actor&  destination)
    {
        destination.health_ -= damage_;
    } 
    //-----------------------------------------------------------------------------------
    void  print()
    {
        std::cout << "Actor "
                  << name_
                  << ":"
                  << std::endl
                  << '\t'
                  << "health: "
                  << health_
                  << std::endl
                  << '\t'
                  << "damage: "
                  << damage_
                  << std::endl
                  << std::endl;
    }
};
///////////////////////////////////////////////////////////////////////////////////////// 
int main()
{
    std::locale::global(std::locale(""));
    T_actor A("A", 100, 50);
    T_actor B("B", 100, 30);
 
    std::cout << "Состояния участников перед схваткой:"
              << std::endl;
    A.print();
    B.print();
 
    A.attack(B);
    B.attack(A);
 
    std::cout << "Состояния участников после схватки:"
              << std::endl;
    A.print();
    B.print();
}
Что касается дружбы, то это самая сильная зависимость, какая только может существовать между классами, а основной принцип ООП - минимизация зависимостей, поэтому дружбы нужно всегда избегать, и применять только тогда, когда без нее невозможно обойтись.
1
║XLR8║
1212 / 909 / 270
Регистрация: 25.07.2009
Сообщений: 4,361
Записей в блоге: 5
13.02.2011, 11:19 9
Цитата Сообщение от Mr.X Посмотреть сообщение
А я что-то не обратил внимания, что классы одинаковые. Тогда логичнее так сделать:
Не могу с вами согласится, так как классы Игрока и Атакованого субьекта могут иметь разную структуру (поля и методы), в связи с чем мой вариант все-таки лучше.
1
54 / 54 / 9
Регистрация: 09.11.2010
Сообщений: 120
13.02.2011, 12:41  [ТС] 10
Mr.X, это они пока одинаковы, т.к. я хочу понять саму суть их взаимоотношений. Как сказал outoftime они действительно будут иметь разную структуру.

Не по теме:

Mr.X, +1 за дружбу =)

0
Эксперт С++
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
13.02.2011, 13:02 11
Цитата Сообщение от outoftime Посмотреть сообщение
Не могу с вами согласится, так как классы Игрока и Атакованого субьекта могут иметь разную структуру (поля и методы), в связи с чем мой вариант все-таки лучше.
Не согласен с вашим несогласием, так как по мнению экспертов защищенные данные – это такое же нарушение инкапсуляции, как и открытые, поэтому их следует избегать.
Ну и если вы наследуете от какого-то класса, то его деструктор нужно обязательно объявлять виртуальным.
Вот так будет логичнее:
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
/////////////////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <string>
/////////////////////////////////////////////////////////////////////////////////////////
typedef std::string  T_name;
/////////////////////////////////////////////////////////////////////////////////////////
class T_actor
{
    T_name  name_;
    int     health_;
    int     damage_;
    //-----------------------------------------------------------------------------------
public:
    //-----------------------------------------------------------------------------------
    T_actor
        (
            T_name  name,
            int     health = 0, 
            int     damage = 0
        ) 
        : name_    (name),
          health_  (health), 
          damage_  (damage)
    {}
    //-----------------------------------------------------------------------------------
    virtual ~T_actor() {}
    //-----------------------------------------------------------------------------------
    void attack(T_actor&  destination)
    {
        destination.health_ -= damage_;
    } 
    //-----------------------------------------------------------------------------------
    virtual void  print()
    {
        std::cout << typeid(*this).name()
                  << " "
                  << name_
                  << ":"
                  << std::endl
                  << '\t'
                  << "health: "
                  << '\t'
                  << health_
                  << std::endl
                  << '\t'
                  << "damage: "
                  << '\t'
                  << damage_                  
                  << std::endl;
    }
    //-----------------------------------------------------------------------------------
    void  println()
    {
        print();
        std::cout << std::endl;
    }
};
///////////////////////////////////////////////////////////////////////////////////////// 
class  T_actor_int : public T_actor
{
    int  int_val_;
    //-----------------------------------------------------------------------------------
public:
    //-----------------------------------------------------------------------------------
    T_actor_int
        (
            T_name  name,
            int     health   = 0, 
            int     damage   = 0,
            int     int_val  = 0
        ) 
        : T_actor   (name, health, damage),         
          int_val_  (int_val)
    {}
    //-----------------------------------------------------------------------------------    
    void  print()
    {
        T_actor::print();
        std::cout << '\t'
                  << "int_val: "
                  << '\t'
                  << int_val_
                  << std::endl;
    }
};
///////////////////////////////////////////////////////////////////////////////////////// 
class  T_actor_double : public T_actor
{
    double  double_val_;
    //-----------------------------------------------------------------------------------
public:
    //-----------------------------------------------------------------------------------
    T_actor_double
        (
            T_name  name,
            int     health      = 0, 
            int     damage      = 0,
            double  double_val  = 0
        ) 
        : T_actor      (name, health, damage),         
          double_val_  (double_val)
    {}
    //-----------------------------------------------------------------------------------    
    void  print()
    {
        T_actor::print();        
        std::cout << '\t'
                  << "double_val: "
                  << '\t'
                  << double_val_
                  << std::endl;
    }
};
///////////////////////////////////////////////////////////////////////////////////////// 
int main()
{
    std::locale::global(std::locale(""));
    T_actor_int     A("A", 100, 50, -1);
    T_actor_double  B("B", 100, 30, -2);
 
    std::cout << "Состояния участников перед схваткой:"
              << std::endl;
    A.println();    
    B.println();    
 
    A.attack(B);
    B.attack(A);
 
    std::cout << "Состояния участников после схватки:"
              << std::endl;
    A.println();
    B.println();
}
0
║XLR8║
1212 / 909 / 270
Регистрация: 25.07.2009
Сообщений: 4,361
Записей в блоге: 5
13.02.2011, 14:37 12
Mr.X, Извените, но вдруг нужно будет менять жизни, к примеру когда подбираешь аптечку, что тогда? Это явно не может делать противник, вернее если писать клиента, то это не надо, из этого следует, что к жизням должны иметь доступ и Игрок и Противник.
Тот-же вопрос по урону: меняем оружие или набиваем опыт.
0
бжни
2473 / 1684 / 135
Регистрация: 14.05.2009
Сообщений: 7,162
13.02.2011, 18:03 13
Лучший ответ Сообщение было отмечено как решение

Решение

Цитата Сообщение от Escapable Посмотреть сообщение
Про "друзей" вопрос открыт.
у Буча об этом остроумно сказано
В дополнение к этому есть еще и механизм друзей, с помощью которого посторонним классам можно предоставить привилегию видеть закрытую и защищенную области класса. Тем самым нарушается инкапсуляция, поэтому, как и в жизни, друзей надо выбирать осторожно.
3
13.02.2011, 18:03
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
13.02.2011, 18:03
Помогаю со студенческими работами здесь

Как сделать массив объектов разных классов?
Как сделать массив объектов разных классов?

Запись и чтение объектов разных классов в один файл
Здравствуйте. Изучаю С++ по Лафоре. Дошёл до места, где объясняется, как записывать объекты разных...

Вектор объектов разных классов. Доступ к свойствам элемента вектора
есть базовый класс class A { //... } есть производные классы class A1 : public A { //......

Как создать массив из объектов разных классов, имеющих общего предка?
Есть основной класc 'Автомобиль' его наследуют 3 класса: мини вен, купе и седан. Как создать...


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

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru