Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: [C++] Организация программ  (Прочитано 9398 раз)
0 Пользователей и 4 Гостей смотрят эту тему.
The Nameless One
Помогающий

ru
Offline Offline
Пол: Мужской

« : 04-11-2009 07:21 » 

Привет)
У меня уточняющие вопросы по поводу организации программ на С++.

В общем, для каждого класса создаем файл one.h, в котором описана его сигнатура, и файл one.cpp, где реализация нашего класса.
Значит, подключать заголовок one.h придется дважды, в файле one.cpp и в main.cpp (где точка входа в прогамму, функция main() или WinMain() ), ну или там, где наш класс будет использован. Я правильно понимаю?

Значит ли это так же и то, что если в нашем классе задейстованы члены из сторонней библиотеки, скажем, классы, описанные в файле fight.h, то этот fight.h будет подключен дважды - в сигнатуре и в реализации класса.

Если я все правильно понял, но не слишком ли все это раздувает размер программы?
-------------------------
Допустим есть класс Space, объявленный в univ.h.
Этот класс будет членом нашего класса Cyborg:

Значит в файле cyborg.h:
Код:
#include "univ.h"
class Cyborg
{
  ...
  Space place;
  void Term();
};

В фале cyborg.cpp:
Код:
#include "cyborg.h"
void Cyborg::Term() {...}

Затем в main.cpp:
Код:
...
#include "univ.h"
int main()
{
   Cyborg one;
   one.Term();
   ...
   return 1;
}

Получается, скомпилированная программа содержит несколько повторяющихся фрагментов кода?
« Последнее редактирование: 04-11-2009 07:24 от The Nameless One » Записан
Sla
Модератор

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 04-11-2009 07:34 » 

И что в процесс компиляции никто не ругается на дублирование переменных при такой организации?

Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
The Nameless One
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 04-11-2009 07:51 » new

Я так никогда не делал Улыбаюсь
Где лишнее include или вообще, как правильно все делать?

Весь вышеизложенный бред - собственные домыслы
« Последнее редактирование: 04-11-2009 08:10 от The Nameless One » Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 04-11-2009 09:22 » 

Наверное, в main.cpp включается всё же cyborg.h, а не univ.h.

А так - всё верно. Один и тот же код, содержащийся в univ.h, попадает в компиляцию столько раз, из скольки модулей он прямо или опосредованно (в составе других заголовков) включён.

Именно поэтому две вещи в заголовках ведут к ошибкам при сборке:
1. Заголовочный файл содержит определение функций, методов классов или глобальных переменных. Тогда после сборки модулей, в процессе линковки выяснится, что скомпилировано несколько экземпляров одноимённых вещей. И будет ошибка линковки, поскольку линковщик не умеет разрешать такие ситуации - он не может установить, что это просто один и тот же код.
2. Заголовочный файл не имеет защиты от повторного включения. Обычно такая защита делается как блок
Код:
#ifndef FOO_H_
#define FOO_H_
// весь код здесь
#endif
или, в Microsoft-стиле, можно просто #pragma once (но я предпочитаю придерживаться 1го варианта, он переносимый).
Такая защита обеспечивает, что если заголовок включается дважды в одном месте, то код второй раз включён не будет. А если защиты нет, будет ошибка компиляции - повторное определение.

В том, что в код повторно включаются заголовки с объявлениями функций и классов и определениями шаблонов - в этом нет ничего страшного. На объём выходного кода это не влияет. Влияет это только на время компиляции, но для ускорения компиляции есть вспомогательные техники. Прежде всего, это так называемая прекомпиляция заголовков - если используешь Visual Studio, там эта методика широко применяется.
« Последнее редактирование: 04-11-2009 09:24 от Вад » Записан
The Nameless One
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 04-11-2009 09:38 » 

Вад, да, кончено же в main.cpp включается cyborg.h, а не univ.h - это я перепутал.

Спасибо большое! Улыбаюсь

Записан
The Nameless One
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 04-11-2009 09:56 » 

Еще можно узнать, почему так делать плохо:

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

А в main.cpp просто подключить этот заголовок и пользоваться?
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #6 : 04-11-2009 10:04 » 

Для чего это вобще нужно.

Вынос имплементирования методов в срр позволяет в больших проектах избегать перекомпиляции всего проекта или частей зависящих от h (в которые заголовочный файл включен) при изменении содержимого метода.

Проще говоря ты делаешь каркас для кучи ф-ций, а потом постепенно заполняешь их. Если в проекте несколько сот cpp, то время экономится значительно. Если же ты используешь только h файлы, то каждое изменение в них приводит к перекомпиляции всех зависимых частей проекта.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
The Nameless One
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 04-11-2009 10:38 » 

Понятно, спасибо)
Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #8 : 04-11-2009 16:09 » 

Еще можно узнать, почему так делать плохо:

в заголовочном файле объявить и ниже сразу же определить его методы.
Плохо - ещё и по указанной выше причине номер один. Если включить такой заголовок, где определены методы и функции, то его можно будет включить только один раз. Как только ты его включишь ещё в какой-то модуль, кроме main.cpp, у тебя будет ошибка линковки.

Из этого правила есть два исключения:
1. никаких таких проблем не будет с inline-ами, то есть, заголовочный файл с кодом:
Код:
class A
{
public:
    void foo() { /* do smth. */ }
    void boo();
};

inline void A::boo()
{
    /* do smth */
}
не будет приводить к проблемам. Ведь, если подумать, реализация inline-функции и правда нужна уже в заголовке - ведь иначе её будет крайне сложно подставить по месту её вызова.

2. Никаких проблем не будет с определением шаблонных функций, и с определением методов шаблонов - тоже.
« Последнее редактирование: 04-11-2009 16:12 от Вад » Записан
The Nameless One
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #9 : 04-11-2009 19:26 » 

Спасибо за помощь)
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines