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

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

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

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

30.10.2015, 15:44. Просмотров 634. Ответов 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
Renji
1925 / 1323 / 298
Регистрация: 05.06.2014
Сообщений: 3,808
30.10.2015, 15:59 #2
Цитата Сообщение от RAFA91 Посмотреть сообщение
Класс B должен содержать обьект класса А , а класс А обьект класса В.
Не взлетит, ибо в общем случае размер таких классов будет бесконечным.
Класс A содержит int x + класс B.
Класс B содержит int y + класс А.
Класс A содержит int x + класс B int y + класс A.
Размер класса A=Размер класса A+размер int x+размер int y
Абсурдность последнего равенства оцените сами.

Ну а решается задача через указатели:
C++
1
2
3
4
5
6
7
8
9
struct A;
struct B
{
    std::unique_ptr<A> x;
};
struct A
{
    std::unique_ptr<B> y;
};
0
RAFA91
Заблокирован
30.10.2015, 16:43  [ТС] #3
Цитата Сообщение от Renji Посмотреть сообщение
Ну а решается задача через указатели:

через указатели на что ?

мне нужно из класса B вызывать методы класса А и наоборот.
0
Renji
1925 / 1323 / 298
Регистрация: 05.06.2014
Сообщений: 3,808
30.10.2015, 16:56 #4
Цитата Сообщение от RAFA91 Посмотреть сообщение
через указатели на что ?
На объекты в динамической памяти, созданные через new A и new B.
Цитата Сообщение от RAFA91 Посмотреть сообщение
мне нужно из класса B вызывать методы класса А и наоборот.
Ну, если только это... Вызывать методы B из A через B_buddy()->B_method().
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
struct B;
struct A
{
    inline B*B_buddy();
};
struct B
{
    inline A*A_buddy();
};
struct AB:A,B
{
};
 
inline A*B::A_buddy(){
    return static_cast<AB*>(this);
}
inline B*A::B_buddy(){
    return static_cast<AB*>(this);
}
0
RAFA91
Заблокирован
30.10.2015, 17:11  [ТС] #5
не вьехал я в этот код. тут сильно много новых причиндалов из с++ 11.

как же раньше решали эту проблему ?

Добавлено через 5 минут
проблемные строки закомментировал.

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
 #include <iostream>
using namespace std;
 
class B;
 
class A
{
    //B b; 
    public:
    A() {cout<<"Конструктор А"<<endl;} 
    void func_1()
    {
        cout<<"Класс А"<<endl;
    }
    void func_2()
    {
        cout<<"Класс А"<<endl;
        //b.func_2();
    }
};
class B
{
    A a;
    public:
    B() {cout<<"Конструктор B"<<endl;} 
    void func_1()
    {
        cout<<"Класс В"<<endl;
        a.func_1();
    }
    void func_2()
    {
        cout<<"Класс В"<<endl;
    }
};
 
int main() 
{
    B b;
    b.func_1();
    return 0;
}
0
Kerry_Jr
Модератор
Эксперт PHP
2201 / 1997 / 700
Регистрация: 14.05.2014
Сообщений: 5,859
Записей в блоге: 1
Завершенные тесты: 5
30.10.2015, 17:16 #6
Цитата Сообщение от RAFA91 Посмотреть сообщение
тут сильно много новых причиндалов из с++ 11.
их тут целых ни одного
0
Renji
1925 / 1323 / 298
Регистрация: 05.06.2014
Сообщений: 3,808
30.10.2015, 17:19 #7
Цитата Сообщение от RAFA91 Посмотреть сообщение
не вьехал я в этот код. тут сильно много новых причиндалов из с++ 11.
Никакого C++11, учите тему "множественное наследование". На пальцах - A и B объединяются в класс AB. Танцуя от предположения "мы лежим в AB", объект A может узнать где лежит объект B и пнуть его метод.
0
Kerry_Jr
Модератор
Эксперт PHP
2201 / 1997 / 700
Регистрация: 14.05.2014
Сообщений: 5,859
Записей в блоге: 1
Завершенные тесты: 5
30.10.2015, 17:20 #8
Цитата Сообщение от RAFA91 Посмотреть сообщение
как же раньше решали эту проблему ?
правильно продумывали иерархию классов.
0
GbaLog-
Любитель чаепитий
2899 / 1356 / 333
Регистрация: 24.08.2014
Сообщений: 4,795
Записей в блоге: 1
Завершенные тесты: 2
30.10.2015, 17:39 #9
RAFA91, Избежать перевключения файлов
0
RAFA91
Заблокирован
30.10.2015, 17:51  [ТС] #10
Цитата Сообщение от Renji Посмотреть сообщение
Никакого C++11
а к чиму тогда эти умные указатели ? про создание третьего класса думал (но без наследований) - но с таким же успехом я могу

обойтись одним мейном.

странно что вы мне не намекнули запихнуть класс А к примеру в класс В
0
Renji
1925 / 1323 / 298
Регистрация: 05.06.2014
Сообщений: 3,808
30.10.2015, 17:53 #11
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от RAFA91 Посмотреть сообщение
а к чиму тогда эти умные указатели ?
К автоматической очистке памяти, причем в другом примере. Умные указатели, кстати, и в C++ были, просто назывались auto_ptr.
1
RAFA91
Заблокирован
30.10.2015, 18:04  [ТС] #12
на данном этапе решения проблемы предположим что обьекты хранятся в стеке или мы сами в состоянии освободить память.

тоесть идея решения заключается в создании класса ниже по иерархии ?
0
Melg
538 / 159 / 64
Регистрация: 23.09.2013
Сообщений: 314
30.10.2015, 18:19 #13
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
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
#include <iostream>
 
using std::cout;
using std::endl;
 
class B;
 
class A {
  B* b_;
 
 public:
  A(B* b) : b_(b) { cout << "Конструктор А" << endl; }
  void func_1();
  void func_2() { cout << "Класс A func_2" << endl; }
};
 
class B {
  A a;
 
 public:
  B() : a(this) { cout << "Конструктор B" << endl; }
 
  void func_1() {
    cout << "Класс В func_1" << endl;
    a.func_1();
  }
 
  void func_2() {
    cout << "Класс В func_2" << endl;
    a.func_2();
  }
};
 
void A::func_1() {
  cout << "Класс А func_1" << endl;
  b_->func_2();
}
 
int main() {
  B b;
  b.func_1();
}
Пруф работоспособности:
http://ideone.com/3EHrZe

Добавлено через 39 секунд
В общем случае стоит избегать двойных связей между классами, и превращать их в односторонние - это улучшит архитектуру приложения за счет снижения зависимости между классами.
0
RAFA91
Заблокирован
31.10.2015, 14:45  [ТС] #14
Цитата Сообщение от Melg Посмотреть сообщение
B() : a(this) { cout << "Конструктор B" << endl; }
не совсем понял эту конструкцию.

или это равносильно

A a(зис); ?
0
Melg
538 / 159 / 64
Регистрация: 23.09.2013
Сообщений: 314
31.10.2015, 16:02 #15
RAFA91, я использовал список инициализации конструктора класса B, в котором вызвал конструктор класса A, для поля класса a передав в него указатель на класс B. В данном случае - указатель на себя.
Подробнее про список инициализации конструктора можно почитать по ссылке:
http://www.learncpp.com/cpp-tutorial...ization-lists/

Добавлено через 1 минуту
Краткий ответ: с точки зрения класса A - да, равносильно. За исключением того факта, что время жизни поля a привязано к времени жизни объекта типа B. А вызов A a(this); - в любой области видимости, меньшей чем класс, заставил бы объект А разрушиться раньше.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
31.10.2015, 16:02
Привет! Вот еще темы с ответами:

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

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

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

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


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

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

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