Взаимно ссылающиеся классы: 1)Проблема описания 2)ошибка IntelliSense
От: Sasha_K  
Дата: 28.03.14 19:41
Оценка:
Столкнулся с такой ситуацией:


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){
   x.d = 123;
}

void main(void) {
   A a;
   E::changeA(a);
   a.show();
}

получаю вывод: "d=123"

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

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

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

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

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

Благодарю за Вашу помощь!
//
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.