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

Предварительное объявление классов. Вызвать функцию до реализации класса - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 13, средняя оценка - 4.92
Russian_Dragon
 Аватар для Russian_Dragon
10 / 11 / 0
Регистрация: 18.02.2012
Сообщений: 140
05.01.2014, 22:36     Предварительное объявление классов. Вызвать функцию до реализации класса #1
Приветствую, народ.
Пытаюсь реализовать структуру типа патерна "Посредник". И при реализации взаимодействий возникла проблемка.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class B;
 
class A {
public:
    B* b;
    void foo(){
        b->foo(); //Вот здесь проблема.
    }
};
 
class B {
public:
    A a;
    void foo(){ 
    }
};
 
int main(){
    B bb = B();
    bb.a.foo();
    return 0;
}
На указанной строке компилятор говорит, что он не может найти реализацию функции.
Может кто-то подсказать, как добиться того, чтобы можно было вызвать функцию до реализации класса?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
05.01.2014, 22:36     Предварительное объявление классов. Вызвать функцию до реализации класса
Посмотрите здесь:

Как использовать функцию класса в другом классе (ни один из классов не наследует другой)? C++
Отделение интерфейса от реализации класса: компиляция кода реализации C++
C++ Как вызвать виртуальную функцию из дочернего класса, если она определена и вызывается в конструкторе РОДИТЕЛЬСКОГО класса?
C++ Предварительное объявление
Как вызвать функцию родительского класса? C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
gromo
 Аватар для gromo
366 / 265 / 24
Регистрация: 04.09.2009
Сообщений: 1,214
05.01.2014, 22:48     Предварительное объявление классов. Вызвать функцию до реализации класса #2
Цитата Сообщение от Russian_Dragon Посмотреть сообщение
как добиться того, чтобы можно было вызвать функцию до реализации класса?
Вы сами-то понимаете, чего хотите?
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11845 / 6824 / 771
Регистрация: 27.09.2012
Сообщений: 16,919
Записей в блоге: 2
Завершенные тесты: 1
05.01.2014, 22:50     Предварительное объявление классов. Вызвать функцию до реализации класса #3
Цитата Сообщение от Russian_Dragon Посмотреть сообщение
чтобы можно было вызвать функцию до реализации класса?
Вынесите реализацию из объявления класса

Добавлено через 1 минуту
Цитата Сообщение от Russian_Dragon Посмотреть сообщение
На указанной строке компилятор говорит, что он не может найти реализацию функции.
Ему известно, что есть класс B, т.к. впереди есть forward declaration, но что этот класс из себя представляет неизвестно в данной строчке.
gromo
 Аватар для gromo
366 / 265 / 24
Регистрация: 04.09.2009
Сообщений: 1,214
05.01.2014, 22:50     Предварительное объявление классов. Вызвать функцию до реализации класса #4
C++
1
extern int func(Class var); // Даже в этом случае, компилятор должен знать о структуре типа Class
Alex566
 Аватар для Alex566
240 / 152 / 18
Регистрация: 03.04.2013
Сообщений: 317
05.01.2014, 23:01     Предварительное объявление классов. Вызвать функцию до реализации класса #5
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class B;
 
class A {
public:
    B* b;
    void foo();
};
 
class B {
public:
    A a;
    void foo();
};
void B::foo() {}
void A::foo() { b->foo(); }
int main(){
    B bb = B();
    bb.a.foo();
    return 0;
}
Russian_Dragon
 Аватар для Russian_Dragon
10 / 11 / 0
Регистрация: 18.02.2012
Сообщений: 140
05.01.2014, 23:02  [ТС]     Предварительное объявление классов. Вызвать функцию до реализации класса #6
[QUOTE=Croessmah;5598302]Вынесите реализацию из объявления класса

Не, так совсем всё плохо будет выглядеть.

----------------------------------------------

Походу придется делать что-то типа Интерфейса. Ибо другие варианты в голову вообще не приходят.
Но, Спасибо за ответы.
outoftime
║XLR8║
 Аватар для outoftime
505 / 427 / 33
Регистрация: 25.07.2009
Сообщений: 2,297
05.01.2014, 23:04     Предварительное объявление классов. Вызвать функцию до реализации класса #7
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
class A;
 
//как минимум публичный описания должны быть
class B {
public:
    A a;
    void foo();
}
 
class A {
public:
    B* b;
    void foo(){
        b->foo(); //Вот здесь проблема.
    }
};
 
// а тут уже реализация
void B::foo(){ 
}
 
int main(){
    B bb = B();
    bb.a.foo();
    return 0;
}
Добавлено через 1 минуту
Т.е. как и сказал Croessmah вынести реализацию за пределы объявления класса.
Russian_Dragon
 Аватар для Russian_Dragon
10 / 11 / 0
Регистрация: 18.02.2012
Сообщений: 140
05.01.2014, 23:05  [ТС]     Предварительное объявление классов. Вызвать функцию до реализации класса #8
Цитата Сообщение от Alex566 Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class B;
 
class A {
public:
    B* b;
    void foo();
};
 
class B {
public:
    A a;
    void foo();
};
void B::foo() {}
void A::foo() { b->foo(); }
int main(){
    B bb = B();
    bb.a.foo();
    return 0;
}
О, интересно.
Ща, попробую поколдовать.
Alex566
 Аватар для Alex566
240 / 152 / 18
Регистрация: 03.04.2013
Сообщений: 317
05.01.2014, 23:07     Предварительное объявление классов. Вызвать функцию до реализации класса #9
Цитата Сообщение от Russian_Dragon Посмотреть сообщение
О, интересно.
Так вам же уже советовали так сделать.
Цитата Сообщение от Croessmah Посмотреть сообщение
Вынесите реализацию из объявления класса
Russian_Dragon
 Аватар для Russian_Dragon
10 / 11 / 0
Регистрация: 18.02.2012
Сообщений: 140
05.01.2014, 23:10  [ТС]     Предварительное объявление классов. Вызвать функцию до реализации класса #10
Alex566, outoftime, да всё собралось спасибо.
Поленился я в .cpp-шник включить ссылку на реализацию класса, думал, что всё это чудо не слинкуется, а нет - заработало. Спасибо всем.
Croessmah
05.01.2014, 23:11
  #11

Не по теме:

Цитата Сообщение от Russian_Dragon Посмотреть сообщение
Не, так совсем всё плохо будет выглядеть.
То есть ошибка прям неописуемо красиво выглядит?

Russian_Dragon
 Аватар для Russian_Dragon
10 / 11 / 0
Регистрация: 18.02.2012
Сообщений: 140
05.01.2014, 23:16  [ТС]     Предварительное объявление классов. Вызвать функцию до реализации класса #12
Цитата Сообщение от Alex566 Посмотреть сообщение
Так вам же уже советовали так сделать.
Да, я - тупанул.
Представил конструкцию где отдельные функции, в них передается экземпляр класса "B".

Добавлено через 3 минуты
Цитата Сообщение от Croessmah Посмотреть сообщение

Не по теме:


То есть ошибка прям неописуемо красиво выглядит?

Как минимум интересный ракурc с ней.
ValeryS
Модератор
6377 / 4843 / 442
Регистрация: 14.02.2011
Сообщений: 16,057
05.01.2014, 23:25     Предварительное объявление классов. Вызвать функцию до реализации класса #13
Цитата Сообщение от Russian_Dragon Посмотреть сообщение
Не, так совсем всё плохо будет выглядеть.
вот для этого и существует разделение на h и cpp файлы
в заголовочных описания класса, в cpp реализация
т.е примерно так
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// myclass.h
class B;
 
class A {
public:
    B* b;
    void foo();
};
 
class B {
public:
    A a;
    void foo();
};
C++
1
2
3
4
5
 
// Myclass.cpp
#include "myclass.h"
void B::foo() {}
void A::foo() { b->foo(); }
outoftime
║XLR8║
 Аватар для outoftime
505 / 427 / 33
Регистрация: 25.07.2009
Сообщений: 2,297
05.01.2014, 23:31     Предварительное объявление классов. Вызвать функцию до реализации класса #14
ValeryS, тут проблема была с перекрестным линкованием а не просто с объявлением класса, так что заголовочные файлы это не совсем то.
ValeryS
Модератор
6377 / 4843 / 442
Регистрация: 14.02.2011
Сообщений: 16,057
05.01.2014, 23:37     Предварительное объявление классов. Вызвать функцию до реализации класса #15
Цитата Сообщение от outoftime Посмотреть сообщение
ValeryS, тут проблема была с перекрестным линкованием а не просто с объявлением класса,
я это понял
я отвечал конкретно на это
Цитата Сообщение от Russian_Dragon Посмотреть сообщение
Не, так совсем всё плохо будет выглядеть.
я так понял что ТС и описания и реализацию запихивает в один файл
тогда это действительно некрасиво
плюс еще если реализация в заголовочном файле, и его подключить несколько раз
то можно получить ошибку линковщика
а так с разделением по файлам и красиво и проблемы уйдут
Russian_Dragon
 Аватар для Russian_Dragon
10 / 11 / 0
Регистрация: 18.02.2012
Сообщений: 140
05.01.2014, 23:48  [ТС]     Предварительное объявление классов. Вызвать функцию до реализации класса #16
Цитата Сообщение от ValeryS Посмотреть сообщение
я так понял что ТС и описания и реализацию запихивает в один файл
тогда это действительно некрасиво
плюс еще если реализация в заголовочном файле, и его подключить несколько раз
то можно получить ошибку линковщика
а так с разделением по файлам и красиво и проблемы уйдут
Здесь был просто упрощенный пример. В реальности архитектура выглядит так [Названия классов тестовые]
C++
1
2
//Global.h
class B;
C++
1
2
3
4
5
6
7
8
//A.h
#include "Global.h"
 
class A {
public:
    B* b;
    void foo();
};
C++
1
2
3
4
5
6
7
//A.cpp
#include "A.h"
 
void A::foo()
{
     b->foo(); //Вот здесь проблема.
}
C++
1
2
3
4
5
6
7
8
//B.h
#include "A.h"
 
class B {
public:
    A a;
    void foo();
};
C++
1
2
3
4
5
//B.cpp
#include "B.h"
void B::foo()
{
}
Почти не читаймо, для быстрого вникания.
Собственно, вот именно такая штука не работала.
В итоге нужно было добавить строку в "A.cpp"
C++
1
2
3
4
//A.cpp
#include "A.h"
#include "B.h"
...
И вот так заработало.
ValeryS
Модератор
6377 / 4843 / 442
Регистрация: 14.02.2011
Сообщений: 16,057
05.01.2014, 23:55     Предварительное объявление классов. Вызвать функцию до реализации класса #17
Цитата Сообщение от Russian_Dragon Посмотреть сообщение
И вот такая штука не работала.
В итоге нужно было добавить строку в "A.cpp"
так сразу бы так и говорил
разумеется ошибка будет поскольку "A.cpp" ничего не знал про класс B, и справедливо ругался.
Цитата Сообщение от Russian_Dragon Посмотреть сообщение
И вот так заработало.
а так узнал
include это такой макрос который весь текст который есть в файле, указанном, переносит заместо себя
ты мог вместо
Цитата Сообщение от Russian_Dragon Посмотреть сообщение
C++
1
2
#include "A.h"
#include "B.h"
написать
Цитата Сообщение от Russian_Dragon Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
10
11
class B;
class A {
public:
 B* b;
 void foo();
};
class B {
public:
 A a;
 void foo();
};
и все бы сработало
но согласись, это глупо
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11845 / 6824 / 771
Регистрация: 27.09.2012
Сообщений: 16,919
Записей в блоге: 2
Завершенные тесты: 1
05.01.2014, 23:56     Предварительное объявление классов. Вызвать функцию до реализации класса #18
Цитата Сообщение от ValeryS Посмотреть сообщение
плюс еще если реализация в заголовочном файле, и его подключить несколько раз
то можно получить ошибку линковщика
Смотря как реализовать всё это дело
ValeryS
Модератор
6377 / 4843 / 442
Регистрация: 14.02.2011
Сообщений: 16,057
05.01.2014, 23:59     Предварительное объявление классов. Вызвать функцию до реализации класса #19
Цитата Сообщение от Croessmah Посмотреть сообщение
Смотря как реализовать всё это дело
если в заголовочном файле есть реализация, и он подключается к разным единицам трансляции ( читай, С-файлы)
то как не реализуй линковщик с ума сойдет, не зная какую реализацию выбрать
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
06.01.2014, 00:00     Предварительное объявление классов. Вызвать функцию до реализации класса
Еще ссылки по теме:

C++ Предварительное объявление класса
Как создать указатель на функцию-член класса и вызвать его? C++
C++ Объявление класса без его реализации

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

Или воспользуйтесь поиском по форуму:
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11845 / 6824 / 771
Регистрация: 27.09.2012
Сообщений: 16,919
Записей в блоге: 2
Завершенные тесты: 1
06.01.2014, 00:00     Предварительное объявление классов. Вызвать функцию до реализации класса #20
ValeryS, попробуйте подключить в разных модулях это:
C++
1
2
3
4
5
6
7
8
9
class A {
public:
    void inline bar ( const char * str ) ;
} ;
 
 
void A::bar ( const char * str ) {
    std::cout << str <<std::endl ;
}
Yandex
Объявления
06.01.2014, 00:00     Предварительное объявление классов. Вызвать функцию до реализации класса
Ответ Создать тему
Опции темы

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