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

Взаимно ссылающиеся классы: 1)Правильное описание 2)ошибки IntelliSense - C++

Восстановить пароль Регистрация
 
SaShka K
3 / 3 / 0
Регистрация: 16.01.2014
Сообщений: 55
31.03.2014, 16:07     Взаимно ссылающиеся классы: 1)Правильное описание 2)ошибки IntelliSense #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
class A;                 //объявление кл. А (т.н. "forward declaration")
 
class E {                   //описание кл. Е
public:
   void static changeA(A&);
};
 
class A {                   //описание кл. А
public:
   A() : d(1) {};
   void show(void) {
      printf("d=%i",d);
   }
   friend void E::changeA(A&);
private:
   int d;
};
 
void E::changeA(A& x){  //определение метода E::changeA() тут (после описания кл. А), т.к. иначе ошибки
   x.d = 123;
}
 
void main(void) {
   A a;
   E::changeA(a);
   a.show();
}
получаю вывод: "d=123"

Тут приведен рабочий код. Изначально у меня были с ним проблемы, когда этот код имел структуру:

forward declaration кл. Е;
описание класса А (полное - вместе с его методами);
описание класса E (полное - вместе с его методами);


В этом случае компилятор ругался: "error C2027: использование неопределенного типа "E" ".
Мой первый вопрос: Подскажите пожалуйста, мне вот не ясно, ведь тип "Е" программа на самом деле уже видит, скорее всего (предполагаю) программа реально не видит при такой последовательности описаний классов не тип E, а его метод E::changeA(). Так ли это? (т.е. компилятор просто нечётко выражается, или это я не понимаю, чего-то).

Но эту проблему смог решить в виде приведённого выше кода — программа заработала.
Вопрос №2: можно ли как-то иначе было решить эту проблему (не перенося описание класса Е перед описанием А. В данном случае класс Е мне пришлось ещё и разорвать: описание класса Е пришлось поместить перед кл. А, а определение метода E::changeA() — после (метод пришлось оставить после А, т.к. он обращается к полю класса А).
Я пытался подобрать нечто вроде прототипа метода changeA() и его указать перед кл. А, тогда все описание Е не пришлось бы переносить, но не удалось (видимо просто невозможно объявить метод вне класса).

Последний 3-ий вопрос: в этом варианте кода всё работает верно, но, тем не менее, IntelliSense выдаёт ошибку (которая, впрочем, не мешает запустить программу):
"IntelliSense: член "A::d" (объявлено в строке 17) недоступно"
и подчёркивает его красным в тексте кода.
Собственно вопрос #3: Почему так? IntelliSense ошибается? (ведь доступно же и корректно выполняемая программа тому подтверждение!) Если действительно ошибается, то как на будущее определить, на какие сообщения IntelliSense об ошибках не стоит обращать внимание?

Благодарю за Вашу помощь!
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
31.03.2014, 16:07     Взаимно ссылающиеся классы: 1)Правильное описание 2)ошибки IntelliSense
Посмотрите здесь:

Построить описание класса (ошибки и вопрос) C++
Сделать описание программы на классы C++
C++ Классы (исправить ошибки)
C++ Полное правильное описание двумерного массива
Классы с наследованием. Описать класс fruit, содержащий поля сорт, размер, описание C++
Программа выдает 3 ошибки. Одна из них: IntelliSense: выражение должно быть допустимым для изменения левосторонним значением C++
C++ Описание чисто виртуальных методов, Абстрактные классы
Правильное swprintf, правильное wprintf ? C++

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

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Wlk
49 / 49 / 13
Регистрация: 07.12.2011
Сообщений: 133
31.03.2014, 16:32     Взаимно ссылающиеся классы: 1)Правильное описание 2)ошибки IntelliSense #2
Разделение интерфейса и реализации очень широкая практика, которая позволяет решить проблемы такого типа. В книге Липпмана, например, советуют следовать следующим правилам:
1. Реализации классов - в файлы "имя_класса.h"
2. Реализации методов класса - в файлы "имя_класса.срр"
Т.б. реализации всех методов класса после реализации класса, в котором объявлены только прототипы.
DrOffset
6446 / 3820 / 885
Регистрация: 30.01.2014
Сообщений: 6,615
31.03.2014, 16:40     Взаимно ссылающиеся классы: 1)Правильное описание 2)ошибки IntelliSense #3
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от SaShka K Посмотреть сообщение
IntelliSense ошибается?
Бывает. Я вот (но это исключительно мое ИМХО) вообще подобным не пользуюсь. С++ довольно сложен для таких инструментов. Поэтому не всегда они работают корректно.

Цитата Сообщение от SaShka K Посмотреть сообщение
можно ли как-то иначе было решить эту проблему (не перенося описание класса Е перед описанием А.
Этот принцип в любом случае останется. Можно добавить красоты по совету Wlk, разнеся это все по h\cpp.

Цитата Сообщение от SaShka K Посмотреть сообщение
Подскажите пожалуйста, мне вот не ясно, ведь тип "Е" программа на самом деле уже видит
Для того, что обращаться к полям и методам - нужно чтобы тип был полным. В С++ (обычно) применяется однопроходная компиляция, поэтому видимость зависит от порядка.
Yandex
Объявления
31.03.2014, 16:40     Взаимно ссылающиеся классы: 1)Правильное описание 2)ошибки IntelliSense
Ответ Создать тему
Опции темы

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