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

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

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 15, средняя оценка - 4.93
Escapable
53 / 53 / 1
Регистрация: 09.11.2010
Сообщений: 120
12.02.2011, 22:39     Взаимодействие объектов разных классов #1
Я или туплю или чего-то не понимаю\не до понимаю. Вопрос в самом коде.
Код
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;
}
Допустим ли такой метод взаимодействия? Как вообще делать "правильно"?
Лучшие ответы (1)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Mr.X
Эксперт С++
 Аватар для Mr.X
2796 / 1572 / 246
Регистрация: 03.05.2010
Сообщений: 3,648
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());        
}
Escapable
53 / 53 / 1
Регистрация: 09.11.2010
Сообщений: 120
12.02.2011, 23:11  [ТС]     Взаимодействие объектов разных классов #3
Mr.X, эм, сижу пытаюсь понять но ... Не могли бы прокомментировать? Что это за конструкции в качестве параметров?

Не по теме:

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

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

А как насчет "друзей"? Пытаться избегать или использовать в разумных пределах?
outoftime
║XLR8║
 Аватар для outoftime
505 / 427 / 33
Регистрация: 25.07.2009
Сообщений: 2,297
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
Escapable
53 / 53 / 1
Регистрация: 09.11.2010
Сообщений: 120
13.02.2011, 01:37  [ТС]     Взаимодействие объектов разных классов #7
outoftime, спасибо за еще одну наводку. О наследовании, в данном случае, чего-то не подумал.

Про "друзей" вопрос открыт.
Mr.X
Эксперт С++
 Аватар для Mr.X
2796 / 1572 / 246
Регистрация: 03.05.2010
Сообщений: 3,648
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();
}
Что касается дружбы, то это самая сильная зависимость, какая только может существовать между классами, а основной принцип ООП - минимизация зависимостей, поэтому дружбы нужно всегда избегать, и применять только тогда, когда без нее невозможно обойтись.
outoftime
║XLR8║
 Аватар для outoftime
505 / 427 / 33
Регистрация: 25.07.2009
Сообщений: 2,297
13.02.2011, 11:19     Взаимодействие объектов разных классов #9
Цитата Сообщение от Mr.X Посмотреть сообщение
А я что-то не обратил внимания, что классы одинаковые. Тогда логичнее так сделать:
Не могу с вами согласится, так как классы Игрока и Атакованого субьекта могут иметь разную структуру (поля и методы), в связи с чем мой вариант все-таки лучше.
Escapable
53 / 53 / 1
Регистрация: 09.11.2010
Сообщений: 120
13.02.2011, 12:41  [ТС]     Взаимодействие объектов разных классов #10
Mr.X, это они пока одинаковы, т.к. я хочу понять саму суть их взаимоотношений. Как сказал outoftime они действительно будут иметь разную структуру.

Не по теме:

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

Mr.X
Эксперт С++
 Аватар для Mr.X
2796 / 1572 / 246
Регистрация: 03.05.2010
Сообщений: 3,648
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();
}
outoftime
║XLR8║
 Аватар для outoftime
505 / 427 / 33
Регистрация: 25.07.2009
Сообщений: 2,297
13.02.2011, 14:37     Взаимодействие объектов разных классов #12
Mr.X, Извените, но вдруг нужно будет менять жизни, к примеру когда подбираешь аптечку, что тогда? Это явно не может делать противник, вернее если писать клиента, то это не надо, из этого следует, что к жизням должны иметь доступ и Игрок и Противник.
Тот-же вопрос по урону: меняем оружие или набиваем опыт.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.02.2011, 18:03     Взаимодействие объектов разных классов
Еще ссылки по теме:

Вектор объектов разных классов. Доступ к свойствам элемента вектора C++
C++ Взаимодействие классов
Взаимодействие классов C++

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

Или воспользуйтесь поиском по форуму:
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
13.02.2011, 18:03     Взаимодействие объектов разных классов #13
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от Escapable Посмотреть сообщение
Про "друзей" вопрос открыт.
у Буча об этом остроумно сказано
В дополнение к этому есть еще и механизм друзей, с помощью которого посторонним классам можно предоставить привилегию видеть закрытую и защищенную области класса. Тем самым нарушается инкапсуляция, поэтому, как и в жизни, друзей надо выбирать осторожно.
Yandex
Объявления
13.02.2011, 18:03     Взаимодействие объектов разных классов
Ответ Создать тему
Опции темы

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