Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 10.08.2016, 11:36   #1
kintel
Пользователь
 
Регистрация: 08.06.2016
Сообщений: 11
По умолчанию Область видимости класса

Всем здравствуйте!
Такая проблема:
Есть два класса: A и B, они оба включаются с помощью #include и должны друг друга видеть.

Выглядит класс A так:

Код:
#pragma once
#include "main.h"

class A{
public:
enum RoleEnum{ first, second, third } role;
A(B *b_ptr) //класс A должен знать о классе B, чтобы создать *b_ptr
{
int var = b_ptr->func(role);
}
};
класс B:
Код:
#pragma once
#include "main.h"

class B{
public:
int func(A::RoleEnum role)//B должен знать об A чтобы знать о RoleEnum
{
switch(role){
case first...return
case second... return
case third...return
}
};
Так выглядит main.h:
Код:
#include "A.h"
#include "B.h"
Так как оба класса должны знать друг о друге, то, в зависимости от того как поменять местами порядок включения файлов в main.h, ошибку выдаёт то класс A, то B.
PS: Насколько я знаю, существуют прототипы классов C++, однако используя их нельзя обращаться к членам класса.

Последний раз редактировалось kintel; 10.08.2016 в 11:40.
kintel вне форума Ответить с цитированием
Старый 10.08.2016, 11:41   #2
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,709
По умолчанию

Не знаю, что вы имели в виду под прототипами классов, но если https://en.wikipedia.org/wiki/Forward_declaration, то последняя часть вашего PS бред и это то, что нужно.
p51x вне форума Ответить с цитированием
Старый 10.08.2016, 11:48   #3
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

А не проще RoleEnum сделать отдельно от А?
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 10.08.2016, 12:06   #4
Croessmah
Вредный кошак
Участник клуба
 
Аватар для Croessmah
 
Регистрация: 14.10.2012
Сообщений: 1,159
По умолчанию

Код:
#pragma once
#include "main.h"

class B;
class A{
public:
   enum RoleEnum{ first, second, third } role;
   A(B *b_ptr);
};


//.cpp
A::A(B *b_ptr)
{
   int var = b_ptr->func(role);
}
Код:
#pragma once
#include "main.h"

class B{
public:
   int func(A::RoleEnum role);
};


//.cpp
int B::func(A::RoleEnum role)
{
   switch(role){
   case first...return
   case second... return
   case third...return
}

Последний раз редактировалось Croessmah; 10.08.2016 в 12:08.
Croessmah вне форума Ответить с цитированием
Старый 10.08.2016, 13:27   #5
kintel
Пользователь
 
Регистрация: 08.06.2016
Сообщений: 11
По умолчанию

p51x, я в нескольких источниках встречал, что нельзя использовать члены не определённого класса. Нельзя даже создавать экземпляр такого класса. Можно только указатель на него, так как указатели имеют фиксированный размер памяти. Из вики про невозможность обращения к методам неопределённого класса:

"Forward declaration of a class is not sufficient if you need to use the actual class type, for example, if you have a member whose type is that class directly (not a pointer), or if you need to use it as a base class, or if you need to use the methods of the class in a method." (https://en.wikipedia.org/wiki/Forwar...ration#Classes)

В моём случае также выдаётся ошибка: "incomplete type is not allowed"

Последний раз редактировалось kintel; 10.08.2016 в 13:51.
kintel вне форума Ответить с цитированием
Старый 10.08.2016, 13:45   #6
kintel
Пользователь
 
Регистрация: 08.06.2016
Сообщений: 11
По умолчанию

Croessmah, чтобы это сработало, обязательно нужно разделять класс на интерфейс и реализацию в двух разных файлах? Просто в моём случае я определяю каждый класс в собственном h-файле. И сейчас всё изменять было бы проблематично. А если в моём случае использовать прототип, выдаются ошибки:
1) argument of type "A::RoleEnum" is incompatible with parameter of type "A::RoleEnum"
2) C2027 use of undefined type 'B'
3) C2227 left of '->func' must point to class/struct/union/generic type
(Все ошибки по отношению к файлу A.h)
kintel вне форума Ответить с цитированием
Старый 10.08.2016, 13:49   #7
kintel
Пользователь
 
Регистрация: 08.06.2016
Сообщений: 11
По умолчанию

Alex11223, проще, конечно. И вообще альтернативные решения этой проблемы есть. Но в конкретном случае мне важно понять как разрешить проблему "связки" и корректной работы двух классов друг с другом. Наверняка в с++ есть решение.
kintel вне форума Ответить с цитированием
Старый 10.08.2016, 13:56   #8
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,709
По умолчанию

Приведите минимальный нерабочий проект
p51x вне форума Ответить с цитированием
Старый 10.08.2016, 14:32   #9
Croessmah
Вредный кошак
Участник клуба
 
Аватар для Croessmah
 
Регистрация: 14.10.2012
Сообщений: 1,159
По умолчанию

Цитата:
чтобы это сработало, обязательно нужно разделять класс на интерфейс и реализацию в двух разных файлах?
Это будет проще, чем шаманить в заголовках и трястись над правильным порядком включения этих заголовков.
Croessmah вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Область видимости chertovich Общие вопросы Delphi 10 24.09.2011 03:21
Область видимости членов класса. Lord-of-Hedgehogs Общие вопросы C/C++ 9 27.11.2010 21:29
Публичная область видимости Бутаков_Сергей Общие вопросы Delphi 1 20.04.2010 09:02
область видимости Dimarik Общие вопросы .NET 5 21.02.2010 21:32
область видимости ? artem779 Общие вопросы Delphi 3 14.09.2007 09:34