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

Объявление взаимодействующих классов - C++

Восстановить пароль Регистрация
 
Sledovatel
 Аватар для Sledovatel
0 / 0 / 0
Регистрация: 13.02.2012
Сообщений: 22
06.10.2012, 21:19     Объявление взаимодействующих классов #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
#include <iostream>
using namespace std;
 
class Word{
    public:
    int length;
    //метод увеличения длины объекта на величину другого объекта l с помощью сумматора s (передаём сумматор и другой объект)
    int sum (Summator * s, Word *l){
        //в метод сумматора передаём ссылку на сам объект и на другой объект
        s -> result(*this, Word *l);
    }
};
 
class Summator{
    public:
    //сумматор увеличивает длину первого объекта на величину длины второго объекта
    void result (Word * w1, Word * w2){
        w1 -> length += w2 -> length;
    }
}
 
int main(){
 
    //создаём два объекта класса Word
    Word * a = new Word();
    Word * b = new Word();
 
    //инициализируем длину каждого объекта
    a -> length = 1;
    b -> length = 2;
 
    //выводим значение длины a
    cout << a -> length << endl;
 
    //создаём объект сумматора
    Sum *s = new Sum();
 
    //длину объекта a с помощью сумматора s увеличиваем на длину объекта b
    a -> sum(s, b);
 
    //выводим значение длины a
    cout << a -> length;
}
Компилятор выдаёт следующие ошибки:

|8|error: 'Summator' has not been declared| (От этой ошибки, похоже, идут все остальные. Получается, классы надо объявлять "одновременно"? Как сделать правильно?)

||In member function 'int Word::sum(int*, Word*)':|
|10|error: request for member 'result' in '* s', which is of non-class type 'int'|
|10|error: expected primary-expression before '*' token|

||In function 'int main()':|
|36|error: 'Sum' was not declared in this scope|
|36|error: 's' was not declared in this scope|
|36|error: expected type-specifier before 'Sum'|
|36|error: expected ';' before 'Sum'|

Заранее большое спасибо за помощь.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.10.2012, 21:19     Объявление взаимодействующих классов
Посмотрите здесь:

C++ Преобразования объектов классов в объекты других классов
Наследование классов. Копирование производных классов C++
C++ объявление директив
C++ объявление массива
C++ Объявление классов
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
doctor_lecter
 Аватар для doctor_lecter
279 / 152 / 8
Регистрация: 22.09.2012
Сообщений: 283
06.10.2012, 21:24     Объявление взаимодействующих классов #2
Компилятор еще "не знает" что есть такой класс, потому что он объявлен ниже. Для этого нужно объявить этот класс выше
C++
1
2
3
4
5
class Summator;
 
class Word {
//...
};
Sledovatel
 Аватар для Sledovatel
0 / 0 / 0
Регистрация: 13.02.2012
Сообщений: 22
06.10.2012, 21:27  [ТС]     Объявление взаимодействующих классов #3
Делал так. Тоже проблемы.
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
#include <iostream>
using namespace std;
 
class Summator;
 
class Word{
    public:
    int length;
    //метод увеличения длины объекта на величину другого объекта l с помощью сумматора s (передаём сумматор и другой объект)
    int sum (Summator * s, Word *l){
        //в метод сумматора передаём ссылку на сам объект и на другой объект
        s -> result(*this, Word *l);
    }
};
 
class Summator{
    public:
    //сумматор увеличивает длину первого объекта на величину длины второго объекта
    void result (Word * w1, Word * w2){
        w1 -> length += w2 -> length;
    }
};
 
int main(){
 
    //создаём два объекта класса Word
    Word * a = new Word();
    Word * b = new Word();
 
    //инициализируем длину каждого объекта
    a -> length = 1;
    b -> length = 2;
 
    //выводим значение длины a
    cout << a -> length << endl;
 
    //создаём объект сумматора
    Sum *s = new Sum();
 
    //длину объекта a с помощью сумматора s увеличиваем на длину объекта b
    a -> sum(s, b);
 
    //выводим значение длины a
    cout << a -> length;
}
||In member function 'int Word::sum(Summator*, Word*)':|
|12|error: invalid use of incomplete type 'struct Summator'|
|4|error: forward declaration of 'struct Summator'|
|12|error: expected primary-expression before '*' token|
||In function 'int main()':|
|38|error: 'Sum' was not declared in this scope|
|38|error: 's' was not declared in this scope|
|38|error: expected type-specifier before 'Sum'|
|38|error: expected ';' before 'Sum'|
||=== Build finished: 7 errors, 0 warnings ===|
doctor_lecter
 Аватар для doctor_lecter
279 / 152 / 8
Регистрация: 22.09.2012
Сообщений: 283
06.10.2012, 21:35     Объявление взаимодействующих классов #4
C++
1
s->sum(this, l);
первый параметр указатель на Word, а *this это конкретный объект, а this - указатель.
Sledovatel
 Аватар для Sledovatel
0 / 0 / 0
Регистрация: 13.02.2012
Сообщений: 22
06.10.2012, 21:39  [ТС]     Объявление взаимодействующих классов #5
Это в какой строке? В 12? Если заменить *this на this, ошибки не уйдут.
doctor_lecter
 Аватар для doctor_lecter
279 / 152 / 8
Регистрация: 22.09.2012
Сообщений: 283
06.10.2012, 21:40     Объявление взаимодействующих классов #6
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Summator;
 
class Word {
// код
int sum (Summator * s, Word *l){
        //в метод сумматора передаём ссылку на сам объект и на другой объект
        s -> result(this, l);
        //еще этот метод должен что-то возвращать
    }
//
};
 
void Summator::result(Word * w1, Word * w2){
        w1 -> length += w2 -> length;
    }
и метод sum должен возвращать значение
Sledovatel
 Аватар для Sledovatel
0 / 0 / 0
Регистрация: 13.02.2012
Сообщений: 22
06.10.2012, 21:57  [ТС]     Объявление взаимодействующих классов #7
Метод int sum переделал в int void, чтобы он не возвращал ничего.
void Summator::result - его так и писать наряду с объявлением классов? Так вроде бы ещё больше ошибок получается.
doctor_lecter
 Аватар для doctor_lecter
279 / 152 / 8
Регистрация: 22.09.2012
Сообщений: 283
06.10.2012, 22:01     Объявление взаимодействующих классов #8
Да, так и писать
Sledovatel
 Аватар для Sledovatel
0 / 0 / 0
Регистрация: 13.02.2012
Сообщений: 22
06.10.2012, 22:15  [ТС]     Объявление взаимодействующих классов #9
А в самом классе Summator оставлять определение этого метода?

Добавлено через 11 минут
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
#include <iostream>
using namespace std;
 
class Summator;
 
class Word{
    public:
    int length;
    //метод увеличения длины объекта на величину другого объекта l с помощью сумматора s (передаём сумматор и другой объект)
    void sum (Summator * s, Word *l){
        //в метод сумматора передаём ссылку на сам объект и на другой объект
        s -> result(this, l);
    }
};
 
class Summator{
    public:
    //сумматор увеличивает длину первого объекта на величину длины второго объекта
    void result (Word * w1, Word * w2);
};
 
void Summator::result(Word * w1, Word * w2){
    w1 -> length += w2 -> length;
}
 
int main(){
 
    //создаём два объекта класса Word
    Word * a = new Word();
    Word * b = new Word();
 
    //инициализируем длину каждого объекта
    a -> length = 1;
    b -> length = 2;
 
    //выводим значение длины a
    cout << a -> length << endl;
 
    //создаём объект сумматора
    Summator *s = new Summator();
 
    //длину объекта a с помощью сумматора s увеличиваем на длину объекта b
    a -> sum(s, b);
 
    //выводим значение длины a
    cout << a -> length;
}
||In member function 'void Word::sum(Summator*, Word*)':|
|12|error: invalid use of incomplete type 'struct Summator'|
|4|error: forward declaration of 'struct Summator'|

Всё-таки есть проблема с объявлением сумматора и с типами данных, которые передаём в sum.
doctor_lecter
 Аватар для doctor_lecter
279 / 152 / 8
Регистрация: 22.09.2012
Сообщений: 283
06.10.2012, 22:25     Объявление взаимодействующих классов #10
так должно работать
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Word;
class Summator{
    public:
    //сумматор увеличивает длину первого объекта на величину длины второго объекта
    void result (Word * w1, Word * w2);
};
 
class Word{
    public:
    int length;
    //метод увеличения длины объекта на величину другого объекта l с помощью сумматора s (передаём сумматор и другой объект)
    void sum (Summator * s, Word *l){
        //в метод сумматора передаём ссылку на сам объект и на другой объект
        s -> result(this, l);
    }
};
 
void Summator::result(Word * w1, Word * w2){
    w1 -> length += w2 -> length;
}
tihonya
11 / 7 / 1
Регистрация: 30.05.2012
Сообщений: 107
06.10.2012, 22:27     Объявление взаимодействующих классов #11
А на*** здесь тот сумматор?
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
//class Summator;
#include <iostream>
using namespace std;
class Word{
    public:
    int length;
    //метод увеличения длины объекта на величину другого объекта l с помощью сумматора s (передаём сумматор и другой объект)
 
  Word* operator + (Word l){
      Word *R = new Word();
      R->length =this->length+l.length;
      return R;
  }
 
};
 
int main(){
 
    //создаём два объекта класса Word
    Word * a = new Word();
    Word * b = new Word();
 
    //инициализируем длину каждого объекта
    a -> length = 1;
    b -> length = 2;
 
    //выводим значение длины a
    cout << a -> length << endl;
    // Складываем
    a= *a+*b ;
  
    //выводим значение длины a
    cout << a -> length;
}
Вот код складывает два объекта Word..
Sledovatel
 Аватар для Sledovatel
0 / 0 / 0
Регистрация: 13.02.2012
Сообщений: 22
06.10.2012, 22:32  [ТС]     Объявление взаимодействующих классов #12
Да, действительно. Так работает.
Теперь остаётся понять, почему такой вариант работает, а предыдущий - с объявлением Summator'a - нет.

Добавлено через 1 минуту
Цитата Сообщение от tihonya Посмотреть сообщение
А на*** здесь тот сумматор?
Мой пример - искусственный, для того чтобы разобраться в объявлении взаимодействующих классов. Но спасибо за пример перегрузки оператора.

Добавлено через 2 минуты
doctor_lecter, такой вариант проходит, а другой нет, потому что Summator не использует методы Word'a? А если бы это было не так, и сумматору приходилось бы запрашивать методы Word'a?
doctor_lecter
 Аватар для doctor_lecter
279 / 152 / 8
Регистрация: 22.09.2012
Сообщений: 283
06.10.2012, 22:40     Объявление взаимодействующих классов #13
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
#include <iostream>
using namespace std;
 
class A;
class B;
 
class A {
public:
    int a;
    int mA(B* b);
};
 
class B {
public:
    int b;
    int mB(A* a);
};
 
int A::mA(B* b) {
    return b->b;
}
 
int B::mB(A* a) {
    return a->a;
}
 
int main() {
    A a;
    B b;
    a.a = 1;
    b.b = 2;
    cout << a.mA(&b) << endl
        << b.mB(&a) << endl;
    return 0;
}
Пример когда классы используют методы и ссылки друг на друга.

Тут в начале можно не объявлять class A;
Sledovatel
 Аватар для Sledovatel
0 / 0 / 0
Регистрация: 13.02.2012
Сообщений: 22
06.10.2012, 22:54  [ТС]     Объявление взаимодействующих классов #14
Все методы одного класса, вызываемые объектом другого класса, должны быть обязательно определены вне класса?
doctor_lecter
 Аватар для doctor_lecter
279 / 152 / 8
Регистрация: 22.09.2012
Сообщений: 283
06.10.2012, 22:55     Объявление взаимодействующих классов #15
Хотя пример получился такой же как и у вас, Summator методы Word не вызывает, но обращается к его свойствам.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
06.10.2012, 23:11     Объявление взаимодействующих классов
Еще ссылки по теме:

C++ Объявление и определение классов
C++ Предварительное объявление классов. Вызвать функцию до реализации класса
C++ Реализация отношения классов типа двунаправленная ассоциация, UML, порядок объявления классов, неполный класс

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

Или воспользуйтесь поиском по форуму:
Sledovatel
 Аватар для Sledovatel
0 / 0 / 0
Регистрация: 13.02.2012
Сообщений: 22
06.10.2012, 23:11  [ТС]     Объявление взаимодействующих классов #16
Или в отдельное определение надо выносить только методы, которые работают с объектами разных классов?
Yandex
Объявления
06.10.2012, 23:11     Объявление взаимодействующих классов
Ответ Создать тему
Опции темы

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