Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Перекрестные ссылки / 14 сообщений из 14, страница 1 из 1
04.07.2018, 11:42
    #39669358
Ciplusor
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перекрестные ссылки
Не могу понять, почему имея два класса я должен указывать что переменная - это класс? Доки перечитал много - везде рекомендуют либо упороться веществами и разводить сотнями дефайнов либо для каждого класса описывать предопределенный класс.

Т.е. это не скомпилируется если не раскомментировать предварительное объявление.

Ship.h
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
#include "Planet.h"
/* class TPlanet; */
class TShip
{
    public:
        TPlanet *planet = nullptr;
}


Planet.h
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
#include "Ship.h"
/* class Ship; */
class TPlanet
{
    public:
        TShip *lastShip = nullptr;
}


Вроде перечитал все что можно было, понятно что чтобы собрать класс ему нужно знать размер переменной. Но ведь он же может сам пойти в соседний файл посмотреть, зачем ему указывать каждый раз? Или может я запутался и неправильно сделал?
...
Рейтинг: 0 / 0
04.07.2018, 11:46
    #39669362
kealon(Ruslan)
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перекрестные ссылки
Ciplusor,

давайте думать логически
компилятор же должен знать сколько места выделять в структуре под элемент?

откуда он это узнаёт?
...
Рейтинг: 0 / 0
04.07.2018, 11:53
    #39669371
Ciplusor
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перекрестные ссылки
kealon(Ruslan), ну как откуда, в соседнем юните написано что TShip - class. Зачем ему второй раз это говорить но уже в области именно его юнита?
...
Рейтинг: 0 / 0
04.07.2018, 12:02
    #39669385
NekZ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перекрестные ссылки
Изи.
Ship.h
Код: plaintext
1.
2.
3.
4.
5.
class TShip
{
    public:
        class TPlanet *planet = nullptr;
}


Planet.h
Код: plaintext
1.
2.
3.
4.
5.
class TPlanet
{
    public:
        class TShip *lastShip = nullptr;
}


И безо всяких инклудов. Инклуды понадобятся только в .cpp.
...
Рейтинг: 0 / 0
04.07.2018, 12:04
    #39669389
kealon(Ruslan)
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перекрестные ссылки
Ciplusor,

просто посмотри как у тебя раскроется

Код: plaintext
1.
2.
#include "Planet.h"
#include "Ship.h"


и наоборот
Код: plaintext
1.
2.
#include "Ship.h"
#include "Planet.h"



в идеале должно получиться

либо
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
class Ship;
class TPlanet
{
    public:
        TShip *lastShip = nullptr;
}
class TShip
{
    public:
        TPlanet *planet = nullptr;
}

либо соответственно
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
class TPlanet;
class TShip
{
    public:
        TPlanet *planet = nullptr;
}
class TPlanet
{
    public:
        TShip *lastShip = nullptr;
}
...
Рейтинг: 0 / 0
04.07.2018, 12:05
    #39669391
NekZ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перекрестные ссылки
kealon(Ruslan),

Можно без форвардных объявлений обойтись
...
Рейтинг: 0 / 0
04.07.2018, 12:06
    #39669393
kolobok0
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перекрестные ссылки
Ciplusor...в соседнем юните написано...

так это не работает...

стэпы компиляции:
компилятор честно берёт файлик и всё что в нём указано в инклудах - он честно инклудит. Сам процесс инклуда - прочитать файлик, распотрошить, все переменные и определения сложить в память перед компиляцией. на момент компиляции кода, все переменные должны быть объявлены тем или иным способом. И компилятор, как дисциплинированный юзверь не полезет перебирать список файликов в поисках того что ему нуна...

как то так
(круглый)
...
Рейтинг: 0 / 0
04.07.2018, 12:11
    #39669396
Ciplusor
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перекрестные ссылки
NekZ, большое спасибо, "изи" вариант легко зашел. Странно что я не натыкался на такое решение.
...
Рейтинг: 0 / 0
04.07.2018, 12:24
    #39669414
kealon(Ruslan)
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перекрестные ссылки
NekZkealon(Ruslan),

Можно без форвардных объявлений обойтись
не знал, занятно что это древняя штука из C, а не плюсов
...
Рейтинг: 0 / 0
04.07.2018, 13:17
    #39669456
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перекрестные ссылки
kealon(Ruslan)не знал, занятно что это древняя штука из C, а не плюсов
В C можно точно так же, только там слово struct :)
...
Рейтинг: 0 / 0
04.07.2018, 13:18
    #39669457
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перекрестные ссылки
А вообще для читаемости кода лучше форвардные объявления выносить отдельно.
Тогда глаз сразу видит что есть взаимные зависимости.
...
Рейтинг: 0 / 0
04.07.2018, 13:35
    #39669471
NekZ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перекрестные ссылки
kealon(Ruslan)не знал, занятно что это древняя штука из C, а не плюсов
Недавно подобный код мне мозг сломал.
Приходится юзать одну сишную либу, в хедере которой есть подобное определение
Код: plaintext
1.
typedef struct foo *Foo;


При учёте, что struct foo больше нигде не был замечен. То есть сразу имеешь тип указателя на структуру в контексте, но самого типа структуры нет.
Поскольку, для работы с этим хэндлом выставлены сишные функции для создания и удаления, решил завернуть это в std::shared_ptr для безопасного
освобождения ресурсов кастомным делитером. Пришлось это организовать так:
Код: plaintext
1.
2.
3.
4.
// так как, формально, в API выставлен именно тип Foo как указатель на фиг пойми что.
std::shared_ptr<std::remove_pointer_t<Foo>> var;
// хотя можно было и так
// std::shared_ptr<struct foo> var;


В общем, плюсовый мир полон открытий даже для опытных разработчиков.
...
Рейтинг: 0 / 0
04.07.2018, 13:45
    #39669475
Ciplusor
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перекрестные ссылки
NekZ[В общем, плюсовый мир полон открытий даже для опытных разработчиков. Не надо меня пугать, мне и так тут страшно, как по минному полю 8(
...
Рейтинг: 0 / 0
05.07.2018, 00:16
    #39669759
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Перекрестные ссылки
CiplusorНе могу понять, почему имея два класса я должен указывать что переменная - это класс? Доки перечитал много - везде рекомендуют либо упороться веществами и разводить сотнями дефайнов либо для каждого класса описывать предопределенный класс.

Т.е. это не скомпилируется если не раскомментировать предварительное объявление.

Ship.h
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
#include "Planet.h"
/* class TPlanet; */
class TShip
{
    public:
        TPlanet *planet = nullptr;
}


Planet.h
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
#include "Ship.h"
/* class Ship; */
class TPlanet
{
    public:
        TShip *lastShip = nullptr;
}




Да, не скомпилируется.
Потому что любой идентификатор должен быть объявлен , чтобы компилятор мог его использовать. По-моему это вполне естественно.
Конкретно это называется forward declaration класса (структуры).

CiplusorВроде перечитал все что можно было, понятно что чтобы собрать класс ему нужно знать размер переменной. Но ведь он же может сам пойти в соседний файл посмотреть, зачем ему указывать каждый раз? Или может я запутался и неправильно сделал?

Не может. Каждый иходный файл компилируется независимо и отдельно от другого.
Ты можешь стереть тот другой файл, скомпилировать этот, он скомпилируется. Затем восстановить тот, а этот удалить, и тот тоже скомпилировать.
Всё будет работать (компилироваться).

Ты можешь два исходника разложить на две разных машины, не связанные по сети, скомпилировать, объектные файлы принести на одну машину и собрать вместе в программу.

Такая вот модель компиляции/сборки в С и С++. Называется "раздельная компиляция".
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Перекрестные ссылки / 14 сообщений из 14, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]