powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Перекрестные ссылки
14 сообщений из 14, страница 1 из 1
Перекрестные ссылки
    #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
Перекрестные ссылки
    #39669362
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ciplusor,

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

откуда он это узнаёт?
...
Рейтинг: 0 / 0
Перекрестные ссылки
    #39669371
Ciplusor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan), ну как откуда, в соседнем юните написано что TShip - class. Зачем ему второй раз это говорить но уже в области именно его юнита?
...
Рейтинг: 0 / 0
Перекрестные ссылки
    #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
Перекрестные ссылки
    #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
Перекрестные ссылки
    #39669391
Фотография NekZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan),

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

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

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

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

Можно без форвардных объявлений обойтись
не знал, занятно что это древняя штука из C, а не плюсов
...
Рейтинг: 0 / 0
Перекрестные ссылки
    #39669456
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)не знал, занятно что это древняя штука из C, а не плюсов
В C можно точно так же, только там слово struct :)
...
Рейтинг: 0 / 0
Перекрестные ссылки
    #39669457
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А вообще для читаемости кода лучше форвардные объявления выносить отдельно.
Тогда глаз сразу видит что есть взаимные зависимости.
...
Рейтинг: 0 / 0
Перекрестные ссылки
    #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
Перекрестные ссылки
    #39669475
Ciplusor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NekZ[В общем, плюсовый мир полон открытий даже для опытных разработчиков. Не надо меня пугать, мне и так тут страшно, как по минному полю 8(
...
Рейтинг: 0 / 0
Перекрестные ссылки
    #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
14 сообщений из 14, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / Перекрестные ссылки
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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