Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/8: Рейтинг темы: голосов - 8, средняя оценка - 4.50
9 / 9 / 8
Регистрация: 24.10.2013
Сообщений: 215

Как правильно расположить заголовочные файлы?

07.04.2016, 19:36. Показов 1698. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте, проблема такая:
Имею три класса
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#ifndef __ACCOUNT_H__
#define __ACCOUNT_H__
 
#include "Post.h"
 
class Account
{
    protected:
        ...
        Post* posts;
};
 
#endif
,
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#ifndef __POST_H__
#define __POST_H__
 
#include "Account.h"
#include "Comment.h"
 
class Post
{
    private:
        Account* likes;
        Comment* comments;
}
 
#endif
и
C++
1
2
3
4
5
6
7
8
9
10
11
12
#ifndef __COMMENT_H__
#define __COMMENT_H__
 
#include "Account.h"
 
class Comment
{
    private:
        Account* owner;
}
 
#endif
Естественно, у меня эти файлы при подключении начинают конфликтовать, так как каждый из них требует наличия другого перед ним. Я могу, конечно, сначала объявить три класса в главном файл main.cpp перед включением этих трёх заголовочных, но это какой-то костыль, по-моему.

Подскажите, пожалуйста, как правильно подключить все три файла?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
07.04.2016, 19:36
Ответы с готовыми решениями:

Как правильно подключать заголовочные файлы?
прошу более продвинутых прогеров чем я найти и/или сделать ту библиотеку которая включает функции ниже. iostream: cin cout ...

Как правильно использовать заголовочные файлы при раздельной компиляции в MS Visual Studio?
Если я использую функцию cout и cin в каждом модуле, мне нужно в каждом модуле прописывать : #include <iostream> using namespace...

Работа в Visual Studio 2015 - как добавить файлы исходного кода и заголовочные файлы?
Приветствую всех! Столкнулся с тем, что решая задачи по книге Лафоре про графику, не смог добавить файлы .h и .cpp, скачав их с одной из...

9
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
07.04.2016, 19:58
Если они друг без друга не работают, зачем разделил? Пусть в одном файле будут.
0
9 / 9 / 8
Регистрация: 24.10.2013
Сообщений: 215
07.04.2016, 20:31  [ТС]
Если я их вместе совмещу, проблема будет такая же и так же решается только написанием
C++ (Qt)
1
2
3
class Account;
class Comment;
class Post;
в начале. Разве нет решения лучше? А если у меня 5000 таких файлов, и вся циклично связаны друг с другом, то что мне делать?
0
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,035
Записей в блоге: 1
07.04.2016, 20:58
Цитата Сообщение от Ryder95 Посмотреть сообщение
то что мне делать?
Пересмотреть структуру проекта?
0
9 / 9 / 8
Регистрация: 24.10.2013
Сообщений: 215
07.04.2016, 21:03  [ТС]
То есть вообще никак по другому?
Ну, например у меня есть два класса, и их объекты должны иметь ссылки друг на друга. Получается, такое реализовать невозможно?
C++
1
2
3
4
class A
{B* pointer;}
class B
{A* pointer;}
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
07.04.2016, 21:32
Ты же сам решение привёл с предварительным объявлением.
1
9 / 9 / 8
Регистрация: 24.10.2013
Сообщений: 215
08.04.2016, 02:32  [ТС]
Ну, оно мне кажется плохим, я думал, есть лучше. Просто привык, что в Python нет проблем с таким объявлением классов и функций, думал, в c++ что-то подобное тоже реализовано.
0
77 / 50 / 16
Регистрация: 17.05.2015
Сообщений: 262
08.04.2016, 03:58
В хедерах записывать только обьявления без include других классов.
class Post* posts;
Пример:
account.h
C++
1
2
3
4
5
6
7
8
9
10
11
#ifndef __ACCOUNT_H__
#define __ACCOUNT_H__
 
class Account
{
    protected:
        ...
       class Post* posts;
};
 
#endif
post.h
C++
1
2
3
4
5
6
7
8
9
10
11
#ifndef __POST_H__
#define __POST_H__
 
class Post
{
    private:
        class Account* likes;
        class Comment* comments;
}
 
#endif
А в реализации уже писать с include.

account.cpp
C++
1
2
3
4
5
6
7
#include "account.h"
#include "post.h"
 
Account::Account()
{
   posts = new Post();
}
post.cpp
C++
1
2
3
4
5
6
7
8
9
#include "Account.h"
#include "Comment.h"
#include "post.h"
 
Post::Post()
{
   likes = new Account();
   comments = new Comment();
}
0
9 / 9 / 8
Регистрация: 24.10.2013
Сообщений: 215
08.04.2016, 09:50  [ТС]
Опять же, в реализации того же Account.cpp первым стоит Account.h, и в нём требуется наличие Post.h. Я, конечно, попробуюу перед ним написать объявление Post, но так файл раздувается сильно из-за хэдеров

Добавлено через 37 минут
Я попробовал сделать так, добавил этот код во все файлы реализации (Account.cpp, Post.cpp, Comment.cpp):
C++
1
2
3
4
5
6
7
8
#include <string>
#include <vector>
 
class Post;
 
#include "Account.h"
#include "Comment.h"
#include "Post.h"
И он почему-то выдаёт мне ошибку, что в Account.h не определены string и тому подобное.
0
47 / 31 / 21
Регистрация: 04.04.2016
Сообщений: 209
08.04.2016, 10:23
C++
1
2
3
4
5
6
7
8
9
10
11
#ifndef __COMMENT_H__
#define __COMMENT_H__
 
class  Account;
 
class Comment
{
private:
Account* owner;
}
#endif
Попробуйте что-то вроде этого в каждом файле. При этом следует учитывать такие особенности СИ++, как:
- объявлять внутри класса ссылку или указатель на другой класс можно с предварительным объявлением данного класса (как в примере выше);
- объявлять внутри класса переменную типа другого класса можно только с предварительным полным определением данного класса (компилятор должен знать размер класса, чтобы выделить ему память). Именно из-за этой особенности не получится сделать зацикленность наподобие вашей, но используя не указатели, а непосредственные переменные;

А теперь давайте посмотрим, что получилось в вашем последнем примере:
C++
1
class Post;
объявили class Post ( кстати, в классе Post не должно быть конструкторов по умолчанию (т.е. конструкторов, не принимающих никаких аргументов, иначе компилятор воспримет эту строку не как объявление, а как создание объекта). Т.к. у вас в ваших классах нет ни одного конструктора, компилятор предоставит вам конструктор по умолчанию сам. Чтобы этого не было, добавьте в каждый класс любой конструктор, принимающий параметр, который, к примеру будет инициализировать ваши указатели. но если пользоваться этой возможностью не собираетесь, можете объявить конструктор в закрытой секции public:
C++
1
#include "Account.h"
Включили account.h, в котором первой же строчкой идет
C++
1
#include "Post.h"
т.е. текст Post.h включится появится перед дальнейшим текстом account.h
А в Post.h у нас идет
C++
1
2
#include "Account.h"
#include "Comment.h"
Account.h мы уже включили - компилятор откидывает его повторное включение благодаря
конструкции
C++
1
2
3
4
#ifndef __ACCOUNT_H__
#define __ACCOUNT_H__
 ...
#endif
А за ним сразу comment.h в котором
C++
1
2
3
4
5
6
7
#include "Account.h"
 
class Comment
{
    private:
        Account* owner;
}
строка #include "Account.h" игнорируется, т.к. препроцессор считает, что данный файл уже включен, хотя на самом деле из него успела включится только первая строка. А далее идет указатель на Account*, класс, определение которого вставиться препроцессором ниже данных строк. т.е. компилятор видя указатель на Account еще ничего не будет знать о том, что это такое. Вот от этого и ошибка. Заменяйте в каждом файле строки
C++
1
2
3
 #include "Account.h"
#include "Comment.h"
#include "Post.h"
на строки
C++
1
2
3
class Account;
class Comment;
class Post;
,
добавляйте в каждый класс по конструктору с параметром и все должно у вас заработать
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
08.04.2016, 10:23
Помогаю со студенческими работами здесь

Перекрестные заголовочные файлы. Как быть?
Есть два класса. Первый знает о втором классе, а второй о первом. Потому ссылки на заголовочные файлы получаются перекрестными. Из-за этого...

Как грамотно подключать заголовочные файлы?
Как грамотно подключать заголовочные файлы? Можно ли их все собрать в stdafx.h а потом инклюдить там где они мне нужны? А то сейчас...

Как подключить между собой заголовочные файлы
Вообщем. У меня есть два класса в разных файлах, они хранят указатели друг друга и при компиляции выводятся куча синтаксических ошибок. IDE...

Как включить исходные и заголовочные файлы в проект? (Dev c++)
Решаю задачки из книги Р.Лафоре &quot;Объектно-ориентированное программирование С++&quot; Есть там пример с использованием консольной графики....

Заголовочные файлы .h, файлы исходного когда c/c++ и установление связи между ними
Всем добрый вечер!) Относительно недавно стал изучать c/c++, хочу полюбопытствовать ,так как появился вопрос. Почему при объявлении...


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

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11680&amp;d=1772460536 Одним из. . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru