С Новым годом! Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
SaShka K
3 / 3 / 0
Регистрация: 16.01.2014
Сообщений: 55
#1

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

31.03.2014, 16:07. Просмотров 774. Ответов 2
Метки нет (Все метки)

Есть такой код:
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 об ошибках не стоит обращать внимание?

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

Ошибки 2064 и 2664, ссылающиеся на библиотеку memory - C++
Здравствуйте, программисты! Преобразовала проект на Java с сырыми указателями на с++ с использованием shared_ptr. Выдает мне 6 ошибок,...

Ошибки intellisense Visual Studio при SFINAE - C++
Добрый вечер, что делать если intellisense Visual Studio не справляется с SFINAE и подчёркивает в любом случаи ?

Полное правильное описание двумерного массива - C++
#include<iostream> #include<cstdlib> #include<ctime> using namespace std; void vvod(int , int, int); void vvod(int f, int n, int...

Программа выдает 3 ошибки. Одна из них: IntelliSense: выражение должно быть допустимым для изменения левосторонним значением - C++
#include <iostream> #include <locale.h> using namespace std; struct PList { int info; PList *prev, *next; ...

Вывести строку-описание указанного возраста, обеспечив правильное согласование числа со словом «год» - C++
Дано целое число в диапазоне 20-69, определяющее возраст (в годах). Вывести строку-описание указанного возраста, обеспечив правильное...

Сделать описание программы на классы - C++
Нужно составить описание этой программы #ifndef complexH #define complexH #include <math.h> ...

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

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

Цитата Сообщение от SaShka K Посмотреть сообщение
Подскажите пожалуйста, мне вот не ясно, ведь тип "Е" программа на самом деле уже видит
Для того, что обращаться к полям и методам - нужно чтобы тип был полным. В С++ (обычно) применяется однопроходная компиляция, поэтому видимость зависит от порядка.
1
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
31.03.2014, 16:40
Привет! Вот еще темы с ответами:

Описание чисто виртуальных методов, Абстрактные классы - C++
Здравствуйте. Изучаю наследование, абстрактные классы. Возникло два вопроса: 1. Видел несколько примеров, вопрос - чем отличаются...

Классы с наследованием. Описать класс fruit, содержащий поля сорт, размер, описание - C++
В программе описать класс fruit содержащий поля сорт, размер, описание. Наследующий классы Apple с полем качество сока и Orrange с полем...

Построить описание класса (ошибки и вопрос) - C++
Это последнее задание из десяти. Я неспал и бошка совсем не варит. Пожалуйста помогите заочнику, а то сдача уже через 2 часа. Собственно...

Классы, проверка на ошибки - C++
Дошел до классов. Написал вот такой код, хочется узнать, совершил ли я какие-либо серьезные ошибки? #include <iostream> // Библиотека...


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

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.