Форум программистов, компьютерный форум CyberForum.ru

Разбиение проекта на файлы - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 8, средняя оценка - 4.88
ququ_smile
1 / 1 / 0
Регистрация: 28.01.2013
Сообщений: 153
17.10.2013, 01:58     Разбиение проекта на файлы #1
Имеется проект, в котором несколько классов, путем проб и ошибок я разделил несколько классов по файлам, но вот что получается, для них всех нужны одинаковые подключенные хедеры и я подключал все эти хедеры в каждом из .cpp файлов(по-другому не работало). То, что везде подключено одно и то же, вызывает у меня плохое чувство... Не может быть всё так тупо, должно быть решение проще. Пожалуйста, подскажите как правильно подключить хедеры. Проект ниже:
Вложения
Тип файла: rar step7.rar (6.16 Мб, 4 просмотров)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
17.10.2013, 01:58     Разбиение проекта на файлы
Посмотрите здесь:

глобальные static-переменные и разбиение на файлы C++
Разбиение программы на файлы С++ C++
Разбиение проекта на .h C++
Разбиение проекта на файлы C++
Разбиение проекта на файлы C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
mytilus
82 / 82 / 8
Регистрация: 04.10.2012
Сообщений: 329
17.10.2013, 06:20     Разбиение проекта на файлы #2
Видимо, вы не до конца разобрались, в чем смысл разделения файлов на *.cpp и *.h. Постараюсь доходчиво объяснить. Надеюсь, получится не очень длинно.
Весь код вы можете писать как в одном cpp-файле, так и в нескольких. Создание нескольких файлов обуславливается только вашими пожеланиями.
Когда вы запустите компиляцию проекта, компилятор все равно соберет коды из всех cpp-файлов вместе, как будто все изначально было написано в одном файле. Но на этапе программирования вы не можете, например, организовать вызов функции в файле a.cpp, если она объявлена в b.cpp. Для этого и существуют хедеры.
h-файлы хранят код, доступ к которому нужен двум или более cpp-файлам. Во время компиляции каждая запись вида
C++
1
#include "путь_к_файлу"
будет заменена на содержимое указанного файла.
Вот пример. У нас есть два файла. Первый - a.cpp:
C++
1
void Main() {HelloWorld();}
Второй - b.cpp:
C++
1
2
#include <windows.h>
void HelloWorld() {MessageBox(NULL, TEXT("Hello World!"), NULL, 0);}
Функция HelloWorld() не может быть вызвана из a.cpp, потому что реализована в b.cpp. Поэтому создаем хедер header.h, в котором объявим эту функцию:
C++
1
void HelloWorld();
В первой строке обоих cpp-файлов напишем:
C++
1
#include "header.h"
И запустим компилятор. Сначала компилятор прочтет все cpp и соберет их в одно целое:
C++
1
2
3
4
5
6
7
8
// a.cpp
#include "header.h"
void Main() {HelloWorld();}
 
// b.cpp
#include "header.h"
#include <windows.h>
void HelloWorld() {MessageBox(NULL, TEXT("Hello World!"), NULL, 0);}
Потом заменит #include на содержимое указанных файлов:
C++
1
2
3
4
5
6
7
8
// a.cpp
void HelloWorld();
void Main() {HelloWorld();}
 
// b.cpp
void HelloWorld();
/* здесь должно быть содержимое файла windows.h */
void HelloWorld() {MessageBox(NULL, TEXT("Hello World!"), NULL, 0);}
А потом уже будет компилировать получившийся код.
Правда, в нашем случае, вылезет ошибка, потому что HelloWorld() объявляется дважды. Поэтому надо переписать header.h:
C++
1
2
3
4
#ifndef MY_HEADER
  #define MY_HEADER
  void HelloWorld();
#endif
Перевести это можно так:
строка 1: если макрос MY_HEADER не объявлен, то
строка 2: объявить макрос MY_HEADER
строка 3: void HelloWorld();
строка 4: конец условия
Тогда после замены инклюдов компилятор получит:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// a.cpp
#ifndef MY_HEADER
  #define MY_HEADER
  void HelloWorld();
#endif
void Main() {HelloWorld();}
 
// b.cpp
#ifndef MY_HEADER
  #define MY_HEADER
  void HelloWorld();
#endif
/* здесь должно быть содержимое файла windows.h */
void HelloWorld() {MessageBox(NULL, TEXT("Hello World!"), NULL, 0);}
А после выполнения директив создаст такой код:
C++
1
2
3
4
5
6
7
// a.cpp
void HelloWorld();
void Main() {HelloWorld();}
 
// b.cpp
/* здесь должно быть содержимое файла windows.h */
void HelloWorld() {MessageBox(NULL, TEXT("Hello World!"), NULL, 0);}
И все будет прекрасно работать.
Если же у нас есть еще один файл - c.cpp - из которого не вызывается HelloWorld(), то строка #include "header.h" ему не нужна.
ququ_smile
1 / 1 / 0
Регистрация: 28.01.2013
Сообщений: 153
17.10.2013, 08:32  [ТС]     Разбиение проекта на файлы #3
Т.е. через хедеры, я не смогу включить другие хедеры 1 раз во все .cpp-шники, да?
ValeryS
Модератор
6377 / 4843 / 442
Регистрация: 14.02.2011
Сообщений: 16,048
17.10.2013, 08:51     Разбиение проекта на файлы #4
mytilus,
сам то понял что написал?

какие это компиляторы собирают все в кучу?
компилятор компилит только единицу трансляции ( чаще всего это один С файл)
и создает объектный модуль
а все вместе собирает линкер, но он работает с объектными модулями, а там ни о каких сишных строках речи не идет

Добавлено через 8 минут
Цитата Сообщение от ququ_smile Посмотреть сообщение
Т.е. через хедеры, я не смогу включить другие хедеры 1 раз во все .cpp-шники, да?
переведи
если у тебя сто заголовков и тебе лень их включать то объедени их в один

типа
C++
1
2
3
4
5
6
// All.h
#include "1.h"
#include "2.h"
#include "3.h"
 
#include "100.h"
и подключай только
All.h
C++
1
#include "All.h"
хотя подключение для каждого модуля много однотипных заголовков может говорить о неправильной архитектуре программы
mytilus
82 / 82 / 8
Регистрация: 04.10.2012
Сообщений: 329
17.10.2013, 09:06     Разбиение проекта на файлы #5
Цитата Сообщение от ququ_smile Посмотреть сообщение
Т.е. через хедеры, я не смогу включить другие хедеры 1 раз во все .cpp-шники, да?
Можете.

Цитата Сообщение от ValeryS Посмотреть сообщение
какие это компиляторы собирают все в кучу?
Не знаю. Я про кучу ничего не писал. Я лишь указывал на безразличие со стороны компилятора на разбиение кода на сорс-файлы.

Добавлено через 2 минуты
Да, действительно. Попутал выше компиляцию с компоновкой.
ququ_smile
1 / 1 / 0
Регистрация: 28.01.2013
Сообщений: 153
17.10.2013, 13:20  [ТС]     Разбиение проекта на файлы #6
Ну вот у меня есть проект, где в каждом хедере описывается какой-то класс, а в соответствующем cpp-шнике его реализация. Класс кнопки использует 2 заголовочных файла библиотеки MFC, а класс окна использует 3 заголовочных файла, 2 из которых те же самые, что и в кнопке. Вопрос в том могу ли я как-то всё записать, чтобы те хедеры, которые подключены к кнопке, относились и к окну.
Yandex
Объявления
17.10.2013, 13:20     Разбиение проекта на файлы
Ответ Создать тему
Опции темы

Текущее время: 20:33. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru