Меня всегда смущали заголовочные файлы. Они такие странные: вы включаете файл .h, который не включает .cpp, но .cpp тоже как-то компилируется.
Недавно я присоединился к командному проекту, и, конечно, используются как .h, так и .cpp.
Я понимаю, что это очень важно, но я не могу жить с копированием каждого объявления функции в каждом из нескольких классов, которые у нас есть.
Как эффективно обрабатывать соглашение из двух файлов?
Существуют ли какие-либо инструменты, чтобы помочь с этим, или автоматически изменить один файл, который выглядит как пример ниже, на .h и .cpp? (специально для MS VC ++ 2010)
class A
{
...
Type f(Type a,Type b)
{
//implementation here, not in another file!
}
...
};
Type f(Type a)
{
//implementation here
}
...
c++
language-design
naming
Олег Припин
источник
источник
Ответы:
Пишем больше рефакторинга на C ++
В C ++ вам не нужно использовать заголовки вообще. Вы можете определить весь объект в одном файле так же, как в C # или Java. Разработчики C обычно хранят только внешние вызовы в заголовочном файле. Все внутренние вызовы будут определены в файле .c. Точно так же вы можете зарезервировать ваши файлы C ++ .h для классов / интерфейсов (чисто виртуальных абстрактных классов) / и т.д. которые предназначены для совместного использования за пределами DLL. Для внутренних классов / структур / интерфейсов и т. Д. Вы просто включите нужный файл .cpp:
Кажется, это не самый популярный подход, но это законный C ++. Это определенно будет возможность для всего вашего внутреннего кода. Это позволяет внутреннему коду и набору классов меняться более радикально, обеспечивая при этом более стабильный интерфейс для взаимодействия кода вне вашей библиотеки / исполняемого файла.
Наличие всего вашего класса в одном файле облегчит выполнение того, что вы хотите. Это не решит проблему переименования метода и необходимости поиска в каждом месте, где вызывается метод, но это обеспечит более понятные сообщения об ошибках. Нет ничего хуже, чем когда ваш заголовок объявляет метод одним способом, но вы реализуете его по-другому. Другой код, который вызывает файл заголовка, будет правильно скомпилирован, и вы получите исключение для ссылки, а файл реализации будет тем, который жалуется на то, что метод не был определен. Когда вы определяете каждый метод на месте (в фактическом объявлении класса), вы получите одно и то же сообщение об ошибке, независимо от того, какой файл содержит его.
Вы также можете посмотреть на этот вопрос: Хорошие инструменты рефакторинга для C ++
Как C / C ++ разрешает файлы заголовка / реализации
На базовом уровне C (а C ++ построен на этой основе), файлы заголовков объявляют обещание функции / struct / variable, которой достаточно, чтобы компилятор мог создать объектный файл. Аналогично, заголовочные файлы C ++ объявляют обещание функций, структур, классов и т. Д. Именно это определение использует компилятор для резервирования пространства в стеке и т. Д.
Файлы .c или .cpp имеют реализацию. Поскольку компилятор преобразует каждый файл реализации в объектный файл, возникают нереализованные понятия (то, что было объявлено в заголовке). Компоновщик связывает хуки с реализациями в других объектных файлах и создает больший двоичный файл, который включает весь код (разделяемая библиотека или исполняемый файл).
VS Specific
Что касается работы с таковыми в Visual Studio, есть несколько мастеров, которые помогают сделать вещи немного проще. Мастер нового класса создаст вашу подходящую пару заголовочных файлов и файлов реализации. Есть даже функция браузера классов, которая позволит вам объявлять новые методы. Он вставит определение в заголовок и заглушку реализации в файл .cpp. Visual Studio имеет эти функции более десяти лет (пока я их использовал).
источник
Станьте разработчиком Java.
Если вам действительно нужно продолжать разработку на C ++, вы можете попробовать использовать IDE. Часто они предлагают какой-то механизм, с помощью которого вы можете добавить метод к классу, и он автоматически помещает объявление в файл .h и определение в файл .cpp.
источник
Вас может заинтересовать программа makeheaders от Hwaci (тех, кто делает SQLite и Fossil).
Также взгляните на то, как строится ископаемое, чтобы иметь представление.
источник
Когда вы пишете первые строки нового класса, это обычно происходит потому, что вам нужно это в одном месте только в это время. Позже он может быть использован в большем количестве мест, но изначально это обычно не так.
Многие из моих классов начинаются в верхней части текущего файла .cpp. Когда он достаточно стабилизируется, чтобы использовать его в нескольких местах, я вставляю его в заголовок. Хотя часто класс исчезает так же быстро, как и появился.
источник
В качестве предложения по обработке заголовочных файлов C ++ обычно их используют без расширения файла или суффикса файла, как это делают библиотеки "GCC".
Если это ваш случай, я предлагаю использовать расширение .hpp (или unleast " .hxx") или суффикс файла.
Возможно, вам придется настроить ваш компилятор, среду разработчика или встроенную программу.
источник
#include <iostream>
? Это не только для библиотеки GCC. Фактически, это определено в стандарте C ++ 1997 года , раздел 17.3.1.2. Я бы не стал называть такие файлы. Вы можете, но причина, по которой стандартная библиотека C ++ сделала это, вероятно, состояла в том, чтобы избежать конфликтов имен. Я действительно нахожу это очень странным, когда компиляторы автоматически добавляют «.h», когда вы включаете заголовок, мне это кажется довольно нестандартным. И я никогда не вижу ни одного заголовка имени без суффикса, за исключением стандартной библиотеки c ++.#include <someclass>
что вас будут читать как#include <someclass.hpp>
на всех компиляторах. Ваш код сломается.