Форум программистов, компьютерный форум, киберфорум
Наши страницы

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

Войти
Регистрация
Восстановить пароль
 
 
RAFA91
Заблокирован
#1

Двухстороннее взаимодействие классов - C++

30.10.2015, 15:44. Просмотров 680. Ответов 29
Метки нет (Все метки)

Добрый день !

Столкнулся с такой технической проблемой.

Есть два класса А и В.

Класс B должен содержать обьект класса А , а класс А обьект класса В.

В результате компиляции получаю ошибки скорее всего из-за неправильного размещения классов.

Подскажите пожалуйста как решить эту проблему.

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
 #include <iostream>
using namespace std;
 
class B;
 
class A
{
    //B b; // ошибка
    public:
    A() {cout<<"Конструктор А"<<endl;} 
    void func_1()
    {
        cout<<"Класс А"<<endl;
    }
};
class B
{
    A a;
    public:
    B() {cout<<"Конструктор B"<<endl;} 
    void func_1()
    {
        cout<<"Класс В"<<endl;
        a.func_1();
    }
};
 
int main() 
{
    B b;
    b.func_1();
    return 0;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.10.2015, 15:44
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Двухстороннее взаимодействие классов (C++):

Взаимодействие классов - C++
Допустим, в первом классе у нас объявлена какая-либо переменная, например проинициализированная строка, объявленная в секции private. Как в...

Взаимодействие классов - C++
Решил потренироваться и написать &quot;игру&quot;. Есть класс игрок и класс бот. Как наладить их взаимодействие? З.Ы. да, я знаю, что в классах нет...

Взаимодействие Двух классов. - C++
Собственно такая проблема: 1 класс использует другой в некоторых ситуациях, из-за этого появляется ошибка base class undefined. Как-то...

Как реализовать взаимодействие классов? - C++
Создаю новую тему ибо новая проблема. Дело в том, что BaseLcd - абстрактная прослойка между устройством и кодом, я отправляю ссылку на...

Взаимодействие объектов разных классов - C++
Я или туплю или чего-то не понимаю\не до понимаю. Вопрос в самом коде. class Player { int health; int damage; public: ...

Разбор полётов: взаимодействие классов - C++
Всем снова здравствуйте, и на этот раз у меня вот такой вопрос: Существует ли структура, которая хранит ссылки на разные классы,...

29
RAFA91
Заблокирован
31.10.2015, 16:14  [ТС] #16
немного поколдовал и пришел к такому решению.

для обмена данными м-ду классами есть два метода transmitter() и receiver()

обьекты создаются в главной функции.

можно ли применять подобный подход или есть более элегантное решение ?

как вообще в жизни делается взаимодействие классов (общение)?

классов взаимодействия может быть много.

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
#include <iostream>
using namespace std;
 
class A
{
    int x;
    int y; //переменная которая будет передана
    int z; //переменная которая была принята
    public:
    A(int a) : x(a),y(0),z(0) {}
    void show() const 
    {
        cout<<"x = "<<x<<" y = "<<y<<" z = "<<z<<endl;
    }
    int transmitter() const {return y;}
    void receiver(int a) {z=a;}
    void calculation() {y=x+z; x += z;}
};
 
class B
{
    int x;
    int y; //переменная которая будет передана
    int z; //переменная которая была принята
    public:
    B(int a) : x(a),y(0),z(0) {}
    void show() const 
    {
        cout<<"x = "<<x<<" y = "<<y<<" z = "<<z<<endl;
    }
    int transmitter() const {return y;}
    void receiver(int a) {z=a;}
    void calculation() {y=x+z; x += z;}
};
 
int main() 
{
    A a(28);
    B b(34);
    a.calculation();
    b.calculation();
    a.show();
    b.show();
    //передача информации от А к В
    b.receiver(a.transmitter());
    //передача информации от B к A
    a.receiver(b.transmitter());
    cout<<"*************************"<<endl;
    a.show();
    b.show();
    
    
    return 0;
}
0
Melg
538 / 159 / 64
Регистрация: 23.09.2013
Сообщений: 314
31.10.2015, 16:33 #17
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
RAFA91, В Вашем случае два класса полностью повторяют функциональность, поэтому можно избавиться от дублирования кода, оставив один класс. Кроме того, названия некоторых Ваших функций и переменных не соответствуют их реальному смысловому значению, поэтому их следует переименовать, для уменьшения семантического шума от Вашего кода. Пример слегка отредактированной версии:
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
#include <iostream>
#include <string>
 
using std::cout;
using std::endl;
 
class A {
 public:
  A(int x) : x_(x) {}
 
  int y() const { return y_; }
 
  void set_z(int z) { z_ = z; }
 
  void show() const {
    cout << "x = " << x_ << " y = " << y_ << " z = " << z_ << endl;
  }
 
  void calculation() {
    y_ = x_ + z_;
    x_ += z_;
  }
 
 private:
  int x_ = 0;
  int y_ = 0;
  int z_ = 0;
};
 
void ShowSeparator() { cout << "*************************" << endl; }
 
int main() {
  A a(28);
  A b(34);
  a.calculation();
  b.calculation();
  a.show();
  b.show();
  //передача информации от А к В
  b.set_z(a.y());
  //передача информации от B к A
  a.set_z(b.y());
  ShowSeparator();
  a.show();
  b.show();
}
Пруф работоспособности:
http://ideone.com/z4V1Lv

Отвечая на Ваш вопрос: если Вам необходимо передавать исключительно данные, без поведения - тогда передача в качестве возвращаемых значений и аргументов функций вполне приемлема. В данном случае вы отделяете код непосредственной логики выполнения (инкапсулируете его в классе), от более высокоуровневой логики, за которую в Вашем случае отвечает функция main. В более сложных ситуациях, когда, например, требуется изменять поведение в процессе работы - используют связку - наследование + виртуальные функции, что дает возможность передавая указатель на базовый (часто абстрактный) класс - в класс - приемник - получать разное поведение приемника, в зависимости от того, какая конкретная реализация базового класса была передана.
1
RAFA91
Заблокирован
31.10.2015, 17:34  [ТС] #18
Цитата Сообщение от Melg Посмотреть сообщение
int x_ = 0;
* int y_ = 0;
* int z_ = 0;
а разве так можно ?

в реале классы А и B отличаются методами которые я не все изложил.

я только привел функции обмена данными для простоты.

как же это привязать к более адекватному подходу общения классов?
0
Renji
2015 / 1383 / 312
Регистрация: 05.06.2014
Сообщений: 3,951
01.11.2015, 04:52 #19
Цитата Сообщение от RAFA91 Посмотреть сообщение
а разве так можно ?
В C++11 - да.
0
RAFA91
Заблокирован
02.11.2015, 15:28  [ТС] #20
Добрый день !
Решил для двухстороннего взаимодействия классов B and C воспользоваться полиморфизмом.
Цель - иметь возможность в одном классе просматривать данные другого класса.
Можно ли применять такой подход взаимодействия классов ?

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
#include <iostream>
using namespace std;
 
class A
{
    protected:
    int x,y,z;
    public:
    A(int a) : x(a),y(a*a),z(a*a*a) {cout<<"Конструктор А "<<this<<endl;}
    virtual ~A() {cout<<"Деструктор А "<<this<<endl;}
    virtual void func_1(A *) const =0 ;
    virtual void func_2() const =0 ;
    int get_x() const {return x;}
    int get_y() const {return y;}
    int get_z() const {return z;}
};
 
class B : public A
{
    public:
    B(int a) : A(a) {cout<<"Конструктор B "<<this<<endl;}
    ~B() {cout<<"Деструктор B "<<this<<endl;}
    void func_1(A *b) const
    {
        cout<<"Данные класса C: ";
        cout<<"x = "<<b->get_x();
        cout<<" y = "<<b->get_y();
        cout<<" z = "<<b->get_z()<<endl;
        b->func_2();
    }
    void func_2() const{cout<<"Класс B x = "<<x
    <<" y = "<<y<<" z = "<<z<<endl;}
};
 
class C : public A
{
    public:
    C(int a) : A(a) {cout<<"Конструктор C "<<this<<endl;}
    ~C() {cout<<"Деструктор C "<<this<<endl;}
    void func_1(A *c) const
    {
        cout<<"Данные класса B: ";
        cout<<"x = "<<c->get_x();
        cout<<" y = "<<c->get_y();
        cout<<" z = "<<c->get_z()<<endl;
        c->func_2();
    }
    void func_2() const{cout<<"Класс C x = "<<x
    <<" y = "<<y<<" z = "<<z<<endl;}
};
 
int main() 
{
    A *c = new C(56);
    A *b = new B(45);
    c->func_1(b);
    b->func_1(c);
    cout<<"***************************"<<endl;
 
 
    return 0;
}
http://ideone.com/zkCdR9
0
castaway
Эксперт С++
4916 / 3024 / 370
Регистрация: 10.11.2010
Сообщений: 11,081
Записей в блоге: 10
Завершенные тесты: 1
02.11.2015, 15:32 #21
Цитата Сообщение от RAFA91 Посмотреть сообщение
Можно ли применять такой подход взаимодействия классов ?
Можно всё что компилируется.
Вопрос в том, устраивает ли тебя такой подход.
0
RAFA91
Заблокирован
02.11.2015, 16:15  [ТС] #22
Цитата Сообщение от castaway Посмотреть сообщение
страивает ли тебя такой подход.

Вы можете предложить более элегантное решение ? В книгах для начинающих не описывается взаимодействие классов, поэтому приходится пользоваться уже тем что более менее знаю.
0
castaway
Эксперт С++
4916 / 3024 / 370
Регистрация: 10.11.2010
Сообщений: 11,081
Записей в блоге: 10
Завершенные тесты: 1
02.11.2015, 16:24 #23
Цитата Сообщение от RAFA91 Посмотреть сообщение
Вы можете предложить более элегантное решение ?
Уже предлагали. Указатели.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
struct A;
struct B;
 
struct A {
    B * m_b;
    void set( B * b ) { m_b = b; }
};
 
struct B {
    A * m_a;
    void set( A * a ) { m_a = a; }
};
 
int main() {
    A a;
    B b;
    a.set( &b );
    b.set( &a );
}
1
RAFA91
Заблокирован
03.11.2015, 15:19  [ТС] #24
Цитата Сообщение от castaway Посмотреть сообщение
Уже предлагали. Указатели.
хранить адрес в классе в принципе отличная идея, но что если обьект был в куче , а потом удален ?

что нужно самому за эти следить и искусственно обнулять указатель ?
0
castaway
Эксперт С++
4916 / 3024 / 370
Регистрация: 10.11.2010
Сообщений: 11,081
Записей в блоге: 10
Завершенные тесты: 1
03.11.2015, 15:33 #25
Цитата Сообщение от RAFA91 Посмотреть сообщение
что нужно самому за эти следить и искусственно обнулять указатель ?
Да. А что, разве это такая большая проблема?
1
RAFA91
Заблокирован
03.11.2015, 15:36  [ТС] #26
ну так это ж как минимум надо лепить метод или открывать поле указателя.
0
Renji
2015 / 1383 / 312
Регистрация: 05.06.2014
Сообщений: 3,951
03.11.2015, 19:47 #27
Цитата Сообщение от RAFA91 Посмотреть сообщение
что нужно самому за эти следить и искусственно обнулять указатель ?
Нет, просто сложить A и B в класс AB.
C++
1
2
3
4
5
6
7
8
class AB
{
public:
    AB():_A(&_B),_B(&_A){}
private:
    A _A;
    B _B;
};
1
RAFA91
Заблокирован
04.11.2015, 14:38  [ТС] #28
Цитата Сообщение от Renji Посмотреть сообщение
Нет, просто сложить A и B в класс AB.
и что мы с этого будим иметь ? накой вообще класс AB нарисовался ?

вот тут опять два обьекта создаются одновременно , а я уже вроде говорил , что они могут создаваться или разрушатся не одновременно.
0
RAFA91
Заблокирован
06.11.2015, 15:30  [ТС] #29
Добрый день !
Для взаимодействия классов решил воспользоваться указателем на функцию в одном из-классе что-бы не опускать реализацию функции func() класса А ниже класса B. А то ведь по хорошему вся реализация методов должна лежать в отдельном файле.
вообщем вот что вышло. есть ли еще более красивый подход ?

______________________________________________

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
#include "stdafx.h"
#include <iostream>
using namespace std;
 
class B;
 
typedef int(B::*Rafa)()const;
 
class A
{
    int x;
    B *b;
    Rafa k;
public:
A(int _x,Rafa _k) : x(_x), k(_k) {cout<<"constructor А "<<this<<endl;}
~A() {cout<<"destructor А"<<this<<endl;}
int get() const {return x;}
void set(B *_b) {b = _b;}
void func(){cout<<"data B: x = "<<(b->*k)()<<endl;} 
};
 
class B
{
    int x;
    A *a;
public:
B(int _x) : x(_x) {cout<<"constructor B "<<this<<endl;}
~B() {cout<<"destructor B"<<this<<endl;}
int get() const {return x;}
void set(A *_a) {a = _a;}
void func() {cout<<"data A: x = "<<a->get()<<endl;}
};
 
 
 
 
int main() 
{
    
    A *a = new A(12,&B::get);
    B *b = new B(165);
    a->set(b);
    b->set(a);
    cout<<"*******************"<<endl;
    a->func();
    b->func();
    return 0;
}
0
RAFA91
Заблокирован
06.11.2015, 16:55  [ТС] #30
******************************************************


не могу понять почему получаю аварийное завершение программы после разнесения классов по файлам. ошибок компиляции нету.

методы лежат в cpp
0
Миниатюры
Двухстороннее взаимодействие классов   Двухстороннее взаимодействие классов   Двухстороннее взаимодействие классов  

Двухстороннее взаимодействие классов   Двухстороннее взаимодействие классов  
06.11.2015, 16:55
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
06.11.2015, 16:55
Привет! Вот еще темы с ответами:

Взаимодействие между объектами единой иерархии классов - C++
Здравствуйте. У меня есть некоторый базовый класс window, который создает &quot;окно&quot; и представляет функции доступа к нему для производных...

Как реализовать взаимодействие классов в игре "Змейка" - C++
Всем привет. Я пишу змейку и у меня следующий вопрос. У меня есть несколько классов Game, Snake, Block, Food. Каждый класс в отдельном...

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

Вынести методы из классов Panel и PictureBox (явная реализация методов базовых абстрактных классов) - C++
Тема: Множественное наследование. Явная реализация методов базовых абстрактных классов. Как вынести методы из классов Panel и...


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

Или воспользуйтесь поиском по форуму:
30
Ответ Создать тему
Опции темы

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