Код C++ в заголовочных файлах

Как я уже говорил, вы должны удалить [] из ngIf.


  
   None
   Option 1
   Option 2
   Option 3
 


You selected: {{selected}}

Рабочий пример можно найти в этом стекаблице

.

183
задан Community 23 May 2017 в 02:34
поделиться

13 ответов

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

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

Наконец, это является часто раздражающим, чтобы иметь круговые объектные отношения (иногда желаемый), когда весь код является заголовками.

Нижняя строка, Вы были правы, он неправ.

РЕДАКТИРОВАНИЕ: я думал о Вашем вопросе. Существует один случай, где то, что он говорит, верно. шаблоны. Многие более новые "современные" библиотеки, такие как повышение делают интенсивное использование шаблонов и часто являются "заголовком только". Однако это должно только быть сделано при контакте с шаблонами, поскольку это - единственный способ сделать это при контакте с ними.

РЕДАКТИРОВАНИЕ: Некоторые люди хотели бы немного больше разъяснения, вот некоторые мысли об оборотных сторонах к записи "заголовка только" код:

, Если Вы ищете вокруг, Вы будете видеть довольно много людей, пытающихся найти способ уменьшить время компиляции при контакте с повышением. Например: , Как уменьшить время компиляции с Asio Повышения, который видит компиляцию 14 единственного 1K файла с включенным повышением. 14, может казаться, не "взрываются", но это, конечно, намного длиннее, чем типичный и может сложить вполне быстро. При контакте с крупным проектом. Заголовок только библиотеки действительно влияет на время компиляции довольно измеримым способом. Мы просто терпим его, потому что повышение так полезно.

Кроме того, существует много вещей, которые не могут быть сделаны в заголовках только (даже повышение имеет библиотеки, с которыми необходимо связаться для определенных частей, таких как потоки, файловая система, и т.д.). Основной пример - то, что у Вас не может быть простых глобальных объектов в заголовке, только освобождает (если Вы не обращаетесь к отвращению, которое является одиночным элементом), поскольку Вы столкнетесь с ошибками повторного определения. ПРИМЕЧАНИЕ: встроенные переменные 17 C++ сделают этот конкретный пример выполнимым в будущем.

Как конечный пункт, при использовании повышения в качестве примера заголовка только кодируют, огромная деталь часто пропускается.

Повышение является библиотекой, не кодом уровня пользователя. таким образом, это часто не изменяет это. В пользовательском коде при помещении всего в заголовки каждое небольшое изменение заставит Вас должными быть перекомпилировать весь проект. Это - монументальная пустая трата времени (и не имеет место для библиотек, которые не изменяются от компиляции до компиляции). То, когда Вы разделяете вещи между заголовком/источником и еще лучше, используйте предописания для сокращения, включает, можно сохранить часы перекомпиляции при складывании через день.

198
ответ дан Community 23 November 2019 в 06:00
поделиться

Не это действительно зависит от сложности системы и внутренних конвенций?

В данный момент я работаю над средством моделирования нейронной сети, которое невероятно сложно, и принятый стиль, который я, как ожидают, буду использовать:

Определения классов в коде класса classname.h
в исполняемом коде classnameCode.h
в classname.cpp

Это разделяет созданные пользователями моделирования от созданных разработчиками базовых классов и работает лучше всего в ситуации.

Однако я был бы удивлен видеть, что люди выполняют в этом, скажем, графическое приложение, или любое другое приложение, это - цель, не должно предоставлять пользователям кодовую базу.

1
ответ дан Ed James 23 November 2019 в 06:00
поделиться

Я вывел всю реализацию из определения класса. Я хочу иметь комментарии doxygen из определения класса.

2
ответ дан Jesus Fernandez 23 November 2019 в 06:00
поделиться

По моему скромному мнению, у Него есть заслуга, ТОЛЬКО ЕСЛИ он делает шаблоны и/или метапрограммирование. Существует много причин, уже упомянул, что Вы ограничиваете заголовочные файлы просто объявлениями. Они - просто это... заголовки. Если Вы хотите включать код, Вы компилируете его как библиотека и соединяете его.

2
ответ дан spoulson 23 November 2019 в 06:00
поделиться

Я лично делаю это в своих заголовочных файлах:

// class-declaration

// inline-method-declarations

мне не нравится смешивать код для методов в с классом, поскольку я нахожу это болью для поиска вещей быстро.

я не поместил бы ВСЕ методы в заголовочном файле. Компилятор (обычно) не будет в состоянии встроить виртуальные методы и (вероятно) только встроит маленькие методы без циклов (полностью зависит от компилятора).

Выполнение методов в классе допустимо..., но с readablilty точки зрения мне не нравится он. Помещение методов в заголовке действительно означает, что, если это возможно, они будут встроены.

4
ответ дан jww 23 November 2019 в 06:00
поделиться

Если этот новый путь действительно Путь , мы, возможно, сталкивались с другим направлением в наших проектах.

, поскольку мы стараемся избегать всех ненужных вещей в заголовках. Это включает каскад заголовка предотвращения. Коду в заголовках propably будет нужен некоторый другой заголовок, который будет включен, которому будет нужен другой заголовок и так далее. Если мы вынуждены использовать шаблоны, мы пробуем, стараются не сорить, заголовки с шаблоном наполняют слишком много.

Также мы используем "непрозрачный указатель" - шаблон , когда применимо.

С этими методами мы можем сделать более быстрые сборки, чем большинство наших коллег. И да... изменяющий код или участников класса не вызовет огромный, восстанавливает.

4
ответ дан Virne 23 November 2019 в 06:00
поделиться

Для добавления большего количества забавы, можно добавить .ipp файлы, которые содержат шаблонную реализацию (который включается в .hpp), в то время как .hpp содержит интерфейс.

Как кроме кода templatized (в зависимости от проекта это может быть большинством или меньшинством файлов) существует нормальный код , и здесь лучше разделить объявления и определения. Предоставьте также предописания при необходимости - это может иметь эффект на время компиляции.

5
ответ дан Anonymous 23 November 2019 в 06:00
поделиться

Часто я буду помещать тривиальные функции членства в заголовочный файл, чтобы позволить им быть встроенными. Но помещать все тело кода там, только согласовываться с шаблонами? Это - простые гайки.

Помните: А глупая непротиворечивость является эльфом небольших умов .

12
ответ дан Mark Ransom 23 November 2019 в 06:00
поделиться

Что могло бы сообщать Вам, что коллега является понятием, что большая часть кода C++ должна быть шаблонной для обеспечения максимального удобства использования. И если это будет шаблонным, тогда все должно будет быть в заголовочном файле, так, чтобы клиентский код видел его и инстанцировал его. Если это достаточно хорошо для Повышения и STL, это достаточно хорошо для нас.

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

19
ответ дан JohnMcG 23 November 2019 в 06:00
поделиться

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

причина А иметь код в заголовочных файлах состоит в том, что он обычно необходим для ключевого слова, встроенного для работы правильно и при использовании шаблонов, это инстанцируется в других cpp файлах.

25
ответ дан Laserallan 23 November 2019 в 06:00
поделиться

Дневные кодеры C++ договариваются Путь , ягнята лягут со львами, палестинцы охватят израильтян, и кошкам и собакам разрешат жениться.

разделение между.h и .cpp файлами главным образом произвольно в этой точке, остатке оптимизации компилятора долго мимо. К моему глазу объявления принадлежат заголовка, и определения принадлежат файла реализации. Но, это - просто привычка, не религия.

148
ответ дан Yes - that Jake. 23 November 2019 в 06:00
поделиться

Обычно при записи нового класса, я помещу весь код в класс, таким образом, я не должен буду смотреть в другом файле для него.. После того, как все будет работать, я изувечил тело методов в cpp файл, оставляя прототипы в hpp файле.

5
ответ дан EvilTeach 23 November 2019 в 06:00
поделиться

Как сказал Туомас, ваш заголовок должен быть минимальным. Для полноты немного расширю.

Я лично использую 4 типа файлов в своих проектах C ++ :

  • Public:
  • Заголовок пересылки: в случае шаблонов и т. Д. Этот файл получает объявления пересылки, которые будут отображаться в заголовке. .
  • Заголовок: этот файл включает заголовок пересылки, если он есть, и объявляет все, что я хочу сделать общедоступным (и определяет классы ...).
  • Закрытый:
  • Закрытый заголовок: этот файл является зарезервированным заголовком для реализации он включает заголовок и объявляет вспомогательные функции / структуры (например, для Pimpl или предикатов). Пропустите, если в этом нет необходимости.
  • Исходный файл: он включает частный заголовок (или заголовок, если нет частного заголовка) и определяет все (не шаблон ...)

Кроме того, я объединяю это с другим правилом: не определяйте, что вы можете пересылать, объявить . Хотя, конечно, я здесь разумный (использовать Pimpl везде довольно хлопотно).

Это означает, что я предпочитаю предварительное объявление директиве #include в моих заголовках, когда мне это удается.

Наконец, я также использую правило видимости: я максимально ограничиваю область действия моих символов, чтобы они не загрязняли внешнюю область видимости.

В целом:

// example_fwd.hpp
// Here necessary to forward declare the template class,
// you don't want people to declare them in case you wish to add
// another template symbol (with a default) later on
class MyClass;
template <class T> class MyClassT;

// example.hpp
#include "project/example_fwd.hpp"

// Those can't really be skipped
#include <string>
#include <vector>

#include "project/pimpl.hpp"

// Those can be forward declared easily
#include "project/foo_fwd.hpp"

namespace project { class Bar; }

namespace project
{
  class MyClass
  {
  public:
    struct Color // Limiting scope of enum
    {
      enum type { Red, Orange, Green };
    };
    typedef Color::type Color_t;

  public:
    MyClass(); // because of pimpl, I need to define the constructor

  private:
    struct Impl;
    pimpl<Impl> mImpl; // I won't describe pimpl here :p
  };

  template <class T> class MyClassT: public MyClass {};
} // namespace project

// example_impl.hpp (not visible to clients)
#include "project/example.hpp"
#include "project/bar.hpp"

template <class T> void check(MyClass<T> const& c) { }

// example.cpp
#include "example_impl.hpp"

// MyClass definition

Спасение здесь в том, что в большинстве случаев прямой заголовок бесполезен: необходим только в случае typedef или шаблона , как и реализация header;)

6
ответ дан 23 November 2019 в 06:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: